GCD 的主队列是一个串行队列。因此,它一次只能运行一个任务。即使该任务运行内部运行循环(例如,运行模式对话框),提交到主队列的其他任务在完成之前也无法运行。
CFRunLoopPerformBlock()
只要运行循环在其中一种目标模式下运行,使用提交的任务就可以运行。这包括运行循环是否从使用CFRunLoopPerformBlock()
.
考虑以下示例:
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");
});
产生如下输出:
outer task milestone 1
inner task
outer task milestone 2
虽然这样:
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");
});
产生:
outer task milestone 1
outer task milestone 2
inner task