[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
NSProgressIndicator movement inside a loop
From: |
Frederico Muñoz |
Subject: |
NSProgressIndicator movement inside a loop |
Date: |
Tue, 01 Mar 2005 02:11:40 +0100 |
Warning, long and boring mail ahead.
I have a doubt about the best way to display a progress bar when the
actions that will affect the progress movement are inside a loop.
Here's my situation: in my Installer I have a packageManager object
that is responsible for dealing with packages (packageManager is
actually a bundle selected according to the package type, but that
doesn't matter). It's a document based app, and MyDocument is the
controller.
When a user clicks "Install" the controller does a [packageManager
installPackage], and that object does the installation. This all works and I
think that it's more or less done propely, at least it works as such
:)
So, here is the problem: in the .pkg bundle the installation at a
certain stage is simply copying a directory to another location. Since
I want to do it file by file I use NSDirectoryEnumerator and copy the
file. I want to have progress bar (progressIndicator) to advance each
time a file is copied, and optionally display the name of the file
above it, etc. I can't pass the NSProgressIndicator to
packageManager's installPackage method since that would ruin the
separation between view and model. This was my first problem. I
decided (but I'm open to suggestions on a better way to do it, I
couldn't think of any...) that the installPackage method would check
for the presence of a updateProgress method in the sender and call it
each time it did something worthy of progression (updateProgress then
uses [progressIndicator incrementBy: X] and related methods to deal
with the progress bar). Simply doing a [sender updateProgress] didn't
work, and this because the NSProgressIndicator is only advanced after
an exit from the method (the run loop only draws theNSProgressIndicator
after exiting the installPackage method, no matter how many times i call
[progressIndicator display] and related methods). I decided to use:
[NSThread detachNewThreadSelector:@selector (installPackage:)
toTarget:packageManager
withObject:self];
to overcome this (please disregard the "self" bit, I'm just
experimenting for now). I set a autorelease pool in the installPackage
method as per the documentation and now it works, I call [sender
updateProgress] inside the copy loop and the progress bar is updated
in real time. However it was brought to my attention that mixing this
call inside a thread might not be very safe and would produce unpredictable
results. I tried with
[sender performSelectorOnMainThread: @selector(updateProgressWithFile:)
withObject: file waitUntilDone: NO];
to be more thread friendly but this doesnt work, since not having it
executing in the main thread (to escape the run loop draw timing) was
the reason I created the thread in the first place, and this way the
problem reapears, the progress bar is only updated after the loop
exits.
So, this is it. I really welcome any advices regarding any issu in
this mail. I must add that dividing the steps into smaller chunks
isn't really doable. I need to update it inside the loop that copies
the file.
Best Regards,
fsmunoz
--
Frederico Muñoz
address@hidden
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- NSProgressIndicator movement inside a loop,
Frederico Muñoz <=