如果我嵌套dispatch_async调用会发生什么?
这可能是一个愚蠢的问题,但我需要为自己问清楚。
要将一个块提交到队列以供执行,请使用dispatch_sync
和dispatch_async
函数。 它们都以队列和块作为参数。 dispatch_async
立即返回,asynchronous运行该块,而dispatch_sync
阻塞执行,直到提供的块返回。 以下是一些情况:
情况1
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul); dispatch_async(queue, ^{ [self goDoSomethingLongAndInvolved]; dispatch_async(queue, ^{ NSLog(@"this is statement1"); }); });
情况2
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul); dispatch_sync(queue, ^{ [self goDoSomethingLongAndInvolved]; dispatch_sync(queue, ^{ NSLog(@"this is statement1"); }); });
情况3
{ [super viewDidLoad]; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul); dispatch_async(queue, ^{ [self goDoSomethingLongAndInvolved]; dispatch_sync(queue, ^{ NSLog(@"this is statement1"); }); });
情况4
{ [super viewDidLoad]; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul); dispatch_sync(queue, ^{ [self goDoSomethingLongAndInvolved]; dispatch_async(queue, ^{ NSLog(@"this is statement1"); }); });
}
而goDoSomethingLongAndInvolved
是
-(void)goDoSomethingLongAndInvolved { NSLog(@"goDoSomethingLongAndInvolved"); }
我试图在Xcode中运行它们,但我根本看不出有什么不同。
所以我的问题是:
- 这些情况之间的主要区别是什么?
- 如果我用
dispatch_get_main_queue()
replacequeue
呢?
dispatch_sync
语句一直等到它所覆盖的块被完全执行。 dispatch_async
立即返回并继续下一行代码,所以里面的所有内容都是并行的。
如果queue
是由您自己创build的串行队列,则:
情况1 – 根块立即返回。 在它内部等待[self go ….],然后去dispatch_async,它也立即返回。
情况2 – 如果queue
是一个串行队列,那么会有一个死锁,因为它会等待自己完成执行。 既然你正在处理asynchronous,那么该块将被并行执行。 (谢谢,@Ken Thomases)
情况3 – 这里不需要dispatch_sync
。 它导致了僵局。
情况4 – 等待[self …],然后立即返回。
如果你用主队列replace队列,那么记住在主队列上不要dispatch_sync
,因为这会导致死锁(如果不是从主线程调度,谢谢@Ken Thomases)。
要更好地理解它,请将您的functionreplace为:
-(void)goDoSomethingLongAndInvolved:(NSString *)message { for(int i = 0; i < 50; ++i) { NSLog(@"%@ -> %d", message, i); } }
你会清楚地看到每一次发生了什么,无论是否等待。 祝你好运。