Re: NSPostWhenIdle not doing its job?
Re: NSPostWhenIdle not doing its job?
- Subject: Re: NSPostWhenIdle not doing its job?
- From: Ken Thomases <email@hidden>
- Date: Mon, 16 May 2011 10:30:22 -0500
On May 16, 2011, at 4:50 AM, Jonathan Taylor wrote:
> Thanks very much for your reply Ken, very helpful indeed.
You're welcome.
>> Still, that won't help if Function B is not being called as often as you expect because NSPostASAP doesn't work like you thought. I suspect that it is only being called when something else tickles the run loop, like user events. I wonder if you click-and-hold in your window (not necessarily on a button or any active control) and just keep dragging the mouse back and forth, if that helps keep the backlog clear. (Simple mouse moves without the mouse button don't send events unless your window has specifically subscribed to them using NSTrackingArea or -setAcceptsMouseMovedEvents:.)
> I've got to be honest, I was very skeptical of this but that is indeed exactly what happens. Bizarre! I wonder if this then suggests a workaround (admittedly a hideous one) of manually posting "user" events to the main loop!?
Well, it's not so hideous and it wouldn't necessarily be simulating user events (mouse clicks, key presses, or the like). NSEvent supports application-defined events, which you can use for this purpose. The -postEvent:atStart: method is even safe to call from background threads; the posted events are still received on the main thread.
> - I am not aware of a way of running code *on*the*main*thread* at low priority (i.e. will not run unless there are "spare" cycles). While GCD has a concept of low priority queues this applies to custom queues, not the main thread where GUI-related code must (I think...) run.
Well, you can submit a block to a low-priority queue whose only work is to submit a block to the main queue:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, NULL), ^{
dispatch_async(dispatch_get_main_queue(), ^{
// Do some work
});
});
This doesn't do coalescing for you, but you can handle that manually. Or, if you're only going to do something like -setNeedsDisplay:, that's coalescing by nature.
> It would not be too hard for me to write my own scheduler which could prioritize the "important" work over the GUI updates, but this really does seem like it shouldn't be necessary! This feels like a fairly common problem to me, so I can't help feeling there must be a standard solution in the cocoa APIs that I am missing...
I think the usual is to just set views as needing display when they do, and the framework and the Window Server will effectively throttle the update frame rate. That is, I don't think there's such a thing as calling -setNeedsDisplay: "too frequently". You just call it when the view is out-of-date with respect to internal state and let things take care of themselves. On the other hand, that does assume that redrawing your view is kept as inexpensive as possible. You shouldn't be doing much computation or hard work in -drawRect:.
Regards,
Ken
_______________________________________________
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