I have the following code that checks the RunLoop in an outerloop and then dispatches to the main_thread in an inner loop using dispatch_after. I have two cases where this is called, once when a button is pressed on the nav bar, and the other case is during viewDidAppear. When the code is called in the later, it remains stuck in the RunLoop and my breakpoint never hits my dispatch_after block. Why is dispatch_after getting blocked? I need to do this to update some progress indicators even while the code is executing. Is is obvious why this might work in one case an not the other? I looked at the stack and there is not much else in the stack.
// case 1:
// does not hit breakpoint
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.4 * NSEC_PER_SEC), dispatch_get_main_queue(), ^
{
[ self longRunningOp ];
});
// case 2:
// This works fine!
[ self longRunningOp ];
-(void) longRunningOp
{
bool dispatched = false;
while (!finished)
{
if (dispatched)
{
// reusing the same date to avoid buffers building up!
date = [ date initWithTimeIntervalSinceNow:0 ];
[ [ NSRunLoop currentRunLoop ] runMode: NSDefaultRunLoopModes beforeDate:date ];
continue;
}
dispatched = true;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.001 * NSEC_PER_SEC), dispatch_get_main_queue(), ^() {
// In second case breakpoint never gets here!
// OPENGL OPS HERE!
dispatched = false;
}
} );
}
I also noticed on other difference.
Success Case: In the case where it works, the UIApplicationMain makes a call out to CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION, this happens when the user presses a nav button.
Failure Case: while in the case where it fails, the UIApplicationMain invokes into CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE, this happens on viewDidAppear.