这可能是一个愚蠢的问题,但我需要为自己提出并清楚这一点。
要将块提交到队列以供执行,请使用函数dispatch_sync
和dispatch_async
。它们都将队列和块作为参数。 dispatch_async
立即返回,异步运行块,而dispatch_sync
阻止执行,直到提供的块返回。以下是一些情况:
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");
});
});
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");
});
});
{
[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");
});
});
{
[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中运行它们,但我看不出它们的区别。
所以我的问题是:
queue
替换为dispatch_get_main_queue()
答案 0 :(得分:16)
dispatch_sync
语句一直等到它覆盖的块完全执行。 dispatch_async
立即返回并继续执行下一行代码,因此内部的所有内容都是并行发生的。
如果queue
是您自己创建的串行队列,则:
情况1 - 根块立即返回。在里面等待[self go ....],然后转到dispatch_async,它也会立即返回。
情况2 - 如果queue
是一个串行队列,则会有一个死锁,因为它会等待自己完成执行。由于您正在处理异步,因此该块将并行执行。 (谢谢,@ Ken Thomases)
情况3 - 此处dispatch_sync
不需要。它导致僵局。
情境4 - 等待[self ...],然后立即返回。
如果用主队列替换queue
,那么记住不要在主队列上dispatch_sync
,因为它会导致死锁(如果没有从主线程发送,则不会发生死锁,感谢@Ken Thomases )。
要更好地理解它,请将您的功能替换为:
-(void)goDoSomethingLongAndInvolved:(NSString *)message {
for(int i = 0; i < 50; ++i) {
NSLog(@"%@ -> %d", message, i);
}
}
无论是否等待,您都会清楚地看到每次发生的事情。祝你好运。