Re: NSRunloop performSelector needs CFRunLoopWakeUp ?
Re: NSRunloop performSelector needs CFRunLoopWakeUp ?
- Subject: Re: NSRunloop performSelector needs CFRunLoopWakeUp ?
- From: Michael Ash <email@hidden>
- Date: Sat, 24 Jan 2009 22:18:52 -0500
On Sat, Jan 24, 2009 at 3:42 PM, David Hoerl <email@hidden> wrote:
> I have a few hundred tasks to handle, and am using NSRunLoop's
> performSelector to get the scheduled:
>
> -(void)nextTask:(SEL)sel
> {
> [[NSRunLoop mainRunLoop] performSelector:sel target:self argument:nil
> order:0
> modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
>
> CFRunLoopRef crf = [[NSRunLoop mainRunLoop] getCFRunLoop];
> CFRunLoopWakeUp(crf);
>
> }
>
> One process sends the first message to the worker object. When the first
> task is done, "nextTask:" is used to schedule the next one.
>
> Well, it was bizarre - before the CFRunLoopWakeUp addition, only 6 or 7 of
> the tasks would run, then the process would stall. NSLogs showed the
> performSelector message, then nothing.
>
> But, wait, there's more! If I clicked on a window, or clicked on a menu,
> then 7 more tasks would run, then another stall. Every click caused 7 more
> messages.
>
> In desperation I added the CFRunLoopWakeUp() call; now it runs as I would
> expect.
>
> There is an oblique reference to CFRunLoopWakeUp in the Threading
> Programming Guide (where documentation on Run Loop Management has moved),
> but the usages is for a different purpose (it would seem).
>
> What seems really odd is that I have used this technique in the past without
> issue. The current app is single threaded.
>
> Can anyone shed any light on why the CFRunLoopWakeUp() call is necessary? Is
> there some other issue I'm missing?
Look at the big master list of what Cocoa classes are thread safe:
http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/chapter_950_section_2.html#//apple_ref/doc/uid/10000057i-CH12-SW4
Notice which category NSRunLoop falls under.
If you are accessing the main thread's NSRunLoop from another thread,
any beneficial behavior you observe is entirely coincidental.
You need to use another technique to avoid violating thread safety
requirements. (One wonders why NSRunLoop even has a +mainRunLoop
method given that it simply can't be used to do anything, but there
you are....) If you're on 10.5, then NSObject has a
-performSelector:onThread:withObject:waitUntilDone: method you can
use. If you need to support previous OSes, then you can use CFRunLoop
(which *is* thread safe, don't know why the CF one is and the NS one
isn't but there you are...) and, of course, you will have to wake it
up after you're done tweaking it as you're doing here.
Mike
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden