如果我嵌套dispatch_async调用会发生什么?

这可能是一个愚蠢的问题,但我需要为自己问清楚。

要将一个块提交到队列以供执行,请使用dispatch_syncdispatch_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中运行它们,但我根本看不出有什么不同。

所以我的问题是:

  1. 这些情况之间的主要区别是什么?
  2. 如果我用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); } } 

你会清楚地看到每一次发生了什么,无论是否等待。 祝你好运。