dispatch_sync 不使用主队列
dispatch_sync not working with main queue
请考虑以下代码:
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 秒,模拟 "hard work"。但是,不幸的是, 它不起作用。我想知道为什么?
我想要的是:dispatch_sync阻塞主线程只有10秒,然后继续执行。
实际发生的情况:分派同步阻止整个应用程序进一步执行。
如果该代码在主事件循环中是 运行,那么 dispatch_group_wait()
将阻塞主队列。这会阻止同步执行主队列上的任何块并导致死锁。
您可以通过暂停进入调试器来验证这一点。您可能会看到主要 thread/queue 在调用 wait 时被阻塞,辅助 thread/queue 在 dispatch_sync.
时被阻塞
您的代码可能在主队列中 运行。它在后台调度三个块,然后等待所有三个块都完成 运行ning。由于这是在主队列上完成的,其他块只会在主队列上开始 运行ning 之后,即在您排队的所有三个异步块都完成之后。
现在这三个块中的第三个块通过同步调用调用主线程。这意味着它向主队列添加一个块,然后等待直到块开始执行,然后它进一步等待直到块完成执行,然后 dispatch_sync 调用 returns 给它的调用者。
好吧,分派给主线程的块无法开始执行,因为主线程正忙于等待三个异步块完成,其中一个不会完成,因为它正在等待分派给的块主线程开始执行,它不能因为等等等等永远。您在同步块中尝试做什么实际上并不重要,因为该块永远不会开始执行。
请考虑以下代码:
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 秒,模拟 "hard work"。但是,不幸的是, 它不起作用。我想知道为什么?
我想要的是:dispatch_sync阻塞主线程只有10秒,然后继续执行。
实际发生的情况:分派同步阻止整个应用程序进一步执行。
如果该代码在主事件循环中是 运行,那么 dispatch_group_wait()
将阻塞主队列。这会阻止同步执行主队列上的任何块并导致死锁。
您可以通过暂停进入调试器来验证这一点。您可能会看到主要 thread/queue 在调用 wait 时被阻塞,辅助 thread/queue 在 dispatch_sync.
时被阻塞您的代码可能在主队列中 运行。它在后台调度三个块,然后等待所有三个块都完成 运行ning。由于这是在主队列上完成的,其他块只会在主队列上开始 运行ning 之后,即在您排队的所有三个异步块都完成之后。
现在这三个块中的第三个块通过同步调用调用主线程。这意味着它向主队列添加一个块,然后等待直到块开始执行,然后它进一步等待直到块完成执行,然后 dispatch_sync 调用 returns 给它的调用者。
好吧,分派给主线程的块无法开始执行,因为主线程正忙于等待三个异步块完成,其中一个不会完成,因为它正在等待分派给的块主线程开始执行,它不能因为等等等等永远。您在同步块中尝试做什么实际上并不重要,因为该块永远不会开始执行。