On 25 Apr 2014, at 1:59 am, edward taffel <[email protected]> wrote:

> thanks  graham,
> 
> i sent performSelectorOnMainThread from readFromURL & the message succeeded, 
> but visually i got the same result: the window did not show until the 
> document window showed. i fear apps may simply not show windows at this point 
> in the load.
> 
> my syntax for the test:
> [self performSelectorOnMainThread:@selector(showReadHUD) withObject:nil 
> waitUntilDone:YES];
> 
> i assume waitUntilDone:YES is the correct thing to do here.


It's hard to comment without knowing what your progress code actually does, but 
it seems to me you're flailing around a bit here without understanding what has 
to happen.

For a window to display "normally", the main thread needs to run its run loop 
"normally" - in other words the run loop loops and visual updates are 
processed. If the main thread is off doing other work, those updates won't 
happen until later. If another thread is doing the work, then the main thread 
can and should loop normally and updates will happen. This is the situation you 
want to ensure is happening, but then you have cross-thread communication which 
must be designed and implemented correctly.

Just invoking your progress code using performSelectorOnMainThread isn't 
necessarily enough, if your code isn't designed to cope with work being done on 
any thread, including possibly the main thread.

If your work code drives progress (not what I am recommending, see below) then 
it too must use performSelectorOnMainThread to update the progress, which in 
turn will mark the views as needing display, which the main thread will perform 
when it gets around to it.

In general, waitUntilDone should be NO so that the work code is not waiting for 
the main thread to get around to performing the update. In the case of a 
document write, the main thread might be busy doing something related to that, 
so you've potentially created a deadlock. For updating progress as work 
proceeds, passing NO can cause too many pending updates to queue up, so 
progress UI gets further and further behind the work. If you pass YES, then 
your work code slows down, throttled by the main thread and limited by how fast 
the UI can update (adding code to the work thread, such as updating in batches, 
is a solution, but to my mind it adds extra code for handling progress that's 
really unnecessary, and interferes with the "purity" of the work code). Neither 
situation is desirable, which is why the polling approach is much better - the 
progress code polls at a leisurely rate, say 10 times per second, and the work 
code proceeds as fast as it can. In the 1/10th second between updates, it can 
process as much data as it can, and it really doesn't matter how much- 100 
cycles or 1,000,000 doesn't matter. The only penalty it pays for being 
monitored by progress is a very brief lock as the main thread reads the "work 
done" value atomically. Progress updates don't pile up, and the work code isn't 
impeded in any meaningful way. I really recommend you do it this way, but you 
might have to redesign your progress UI and controller a bit, though perhaps 
not too much - it's  just a case of adding a timer to perform the polling and 
setting the progress bar control's value.

--Graham



_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to