The main GCD queue is the next queue. Thus, it can only run one task at a time. Even if this task performs an internal loop of the cycle, for example, starts a modal dialog, then other tasks sent to the main queue cannot be executed until this is completed.
Tasks dispatched using CFRunLoopPerformBlock() can be executed whenever the start cycle starts in one of the target modes. This includes if the run loop starts from a task that was submitted using CFRunLoopPerformBlock() .
Consider the following examples:
CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, ^{ printf("outer task milestone 1\n"); CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, ^{ printf("inner task\n"); }); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; printf("outer task milestone 2\n"); });
produces a conclusion, for example:
outer task milestone 1 inner task outer task milestone 2
So far it is:
dispatch_async(dispatch_get_main_queue(), ^{ printf("outer task milestone 1\n"); dispatch_async(dispatch_get_main_queue(), ^{ printf("inner task\n"); }); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; printf("outer task milestone 2\n"); });
gives:
outer task milestone 1 outer task milestone 2 inner task
Ken thomases
source share