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 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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]