I am building a custom GLKView
using on-demand rendering. Most of the time the view will only redraw on touch events (and this is working), but sometimes there are short animations where I would like to redraw in a loop.
My first attempt looked like this:
-(void)drawRect:(CGRect)rect {
NSLog(@"Jo");
glClearColor(1, 0, 0, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[self setNeedsDisplay];
}
My understanding coming from Android
was, that this should keep clearing the screen as fast as possible and logging lots of "Jo".
What actually happens is that "Jo" is logged roughly once per second, the view is never cleared at all, yet CPU
use remains 0.
If I change
[self setNeedsDisplay];
to
dispatch_async(dispatch_get_main_queue(), ^{
[self setNeedsDisplay];
});
everything works exactly as expected.
As far as I understand drawRect
is called from the main thread anyway, so why does the dispatch_async
make a difference?
So now I have three questions:
- What is happening in that one second between the "Jo" logs?
- Why is
dispatch_async
making a difference? - Is it bad practice to use this approach in production?
Thank you very much!
EDIT:
There is one more thing I don't understand.
When I'm using the [self setNeedsDisplay];
method, all other calls on the main queue seem to be starving. Touch events no longer fire and a callback from RestKit never gets delivered. Does [self setNeedsDisplay];
somehow not get added at the end of the queue, but in the beginning?