[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: NSProgressIndicator movement inside a loop
From: |
Richard Frith-Macdonald |
Subject: |
Re: NSProgressIndicator movement inside a loop |
Date: |
Thu, 3 Mar 2005 12:05:55 +0000 |
On 3 Mar 2005, at 11:33, Frederico Muñoz wrote:
because I don't think
notifications are guaranteed to be delivered in a particular thread.
If you
post them for immediate delivery, they are generally delivered to the
same
thread that posts them, and if they are posted in a queue, they are
generally
delivered in the first thread to execute a run loop ... which may be
what is
happening in your current code, and why it's working.
I'm using [[NSNotificationCenter defaultCenter] postNotificationName:
@"ProgressShouldUpdate" object: file].
Then I expect that the notifications are being delivered in the
installer thread,
which means that you are really getting the same effect as if you called
-incrementBy: directly.
The correct way (as I understand it) is to perform the slow install
operation
in a second thread,
and at intervals when milestones in the install operation are
completed, call
-performSelectorOnMainThread:withObject:waitUntilDone:
with the 'waitUntilDone' flag set to NO.
Ok, this was my previous way of doing things, check for the selector
and call it in the installer thread. The only difference is that I'm
not using milestones, I'm calling it inside a loop that copies files.
The problem for me in setting milestones is that in the .pkg
installation process 99% of what is done is "copy files listes in this
enumerator to this destination". I could trigger it at intervals, say
each time 10 files are copied or something, but wouldn't this work the
same way as doing it each time a file is copied?
Yes ... I only said 'milestones' meaning that you might want to
estimate total time taken at
the start of the process, and try to make your calls to -incrementBy:
match that time so that the
progress indication the user sees is as accurate as possible.
This lets the main thread run normally during the install, and update
the
progress bar at intervals when the installer thread tells it to.
Using this
method guarantees that the update
of the progress bar is done in the main thread ... which is the only
thread
that it's safe to
perform gui updates in.
Well, I'm probably missing something but even using notifications from
the installer thread the update of the progress bar is only done in
the main thread, or at least that's the way it looks to me. The
updateProgress method in the maint thread is the one registered to
handle the notification, and it is only there that any UI code is in
any way touched. The installer thread doesn't even know about the UI
instances being used.
Yes ... the reason this is all working is that the -incrementBy: method
does not actually do
any drawing. It just marks the progress indicator as needing display
(calling -setNeedsDisplay:).
Fortunately, -setNeedsDisplay: checks which thread it is executing, and
if it's not in the main thread, uses
-performSelectorOnMainThread:withobject:waitUntilDone: to call itsself
in the main thread.
This means that you are safe calling the gui method from the installer
thread in this case ...
but it's not generally good.