请考虑以下代码:
dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t myGroup = dispatch_group_create();
dispatch_group_async(myGroup, myQueue, ^{
NSLog(@"First block of code");
});
dispatch_group_async(myGroup, myQueue, ^{
NSLog(@"Second block of code");
});
dispatch_group_async(myGroup, myQueue, ^{
dispatch_sync(dispatch_get_main_queue(), ^{ //problem here
dispatch_time_t myTime = dispatch_time(DISPATCH_TIME_NOW, 10ull * NSEC_PER_SEC);
dispatch_after(myTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"Third block of code work");
});
});
});
dispatch_group_wait(myGroup, DISPATCH_TIME_FOREVER);
NSLog(@" All done ?");
问题出在dispatch_sync(dispatch_get_main_queue(), ^{
当我发出dispatch_async(dispatch_get_main_queue(),^ {时,它可以正常工作。进行同步的点是阻塞主线程10秒,模拟“努力工作”。但不幸的是,它不起作用。我想知道为什么?
我想要的是:dispatch_sync 阻止主线程仅10秒,然后继续执行。
事实上发生了什么:从任何进一步的执行中调度同步块整个应用程序。
答案 0 :(得分:2)
如果该代码在主事件循环上运行,则dispatch_group_wait()
将阻止主队列。这可以防止主队列上任何块的同步执行,并导致死锁。
您可以通过暂停调试器来验证这一点。您可能会在调用等待时看到主线程/队列被阻塞,并且在dispatch_sync上阻塞了辅助线程/队列。
答案 1 :(得分:1)
您的代码可能在主队列上运行。它在后台调度三个块,然后等待,直到所有三个块都完成运行。由于这是在主队列上完成的,因此其他块将仅在之后开始在主队列上运行,即在排队的所有三个异步块完成之后。
现在这三个块中的第三个用同步调用调用主线程。这意味着它是向主队列添加一个块,然后它等待直到块开始执行,然后它等待直到块完成执行,然后dispatch_sync调用返回到它的调用者。
好吧,调度到主线程的块无法开始执行,因为主线程忙于等待三个异步块完成,其中一个块无法完成,因为它正在等待调度到主线程的块线程开始执行,它不能因为等等永远。实际上,在同步块中尝试执行的操作实际上并不重要,因为该块永远不会开始执行。