[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

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:)

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

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,

Frederico Muñoz

reply via email to

[Prev in Thread] Current Thread [Next in Thread]