这两种实现之间是否存在差异:
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
__block UIImage *image = nil;
dispatch_sync(concurrentQueue, ^{
/* Download the image here sync downloading */
});
dispatch_sync(dispatch_get_main_queue(), ^{
/* Show the image to the user here on the main queue */
});
});
和
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
__block UIImage *image = nil;
/* Download the image here sync downloading */
dispatch_sync(dispatch_get_main_queue(), ^{
/* Show the image to the user here on the main queue */
});
});
在第一个代码中,我通过调度同步使用块下载图像,而在第二个代码中我无需下载就下载它!
我认为我应该在第一个实现中遇到死锁,因为Apple说:dispatch_sync->调用此函数并定位当前队列会导致死锁
答案 0 :(得分:2)
我认为我应该在第一个实现中遇到死锁,因为苹果说:dispatch_sync->调用此函数并定位当前队列会导致死锁
如果队列是串行队列,则为true。但是,在这种情况下,您正在使用全局队列,因此永远不会发生死锁。所以区别在于哪个线程将在全局队列线程池中执行Download the image here sync downloading
。
首次实施
main queue -----------+---------------------------------+-----------+------
async(global)| ^ |
v sync(main)| v
global queue thread1 +-----+BLOCKED +-----------+BLOCKED +------
sync(global)| ^
v |
global queue thread2 +---------------+
第二次实施
main queue -----------+---------------------------------+-----------+------
async(global)| ^ |
v sync(main)| v
global queue thread1 +---------------------------------+BLOCKED +------
但是在这种情况下,dispatch_sync并不是一个好主意。 https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html
重要提示:永远不要从正在计划传递给函数的同一队列中执行的任务调用dispatch_sync或dispatch_sync_f函数。这对于保证死锁的串行队列尤其重要,但对于并发队列也应避免使用。
......即使我找不到dispatch_sync should also be avoided for concurrent queues
的任何证据
http://opensource.apple.com/source/libdispatch/libdispatch-339.92.1/src/queue.c
答案 1 :(得分:1)
dispatch_sync dispatch_get_main_queue()立即完成了操作。因为我们正在主队列中执行阳离子。这里我们正在进行UI更新以及延迟加载和异步下载等所有内容。
它与GCD有关,详情请参阅AppleDevelopers论坛。
使用dispatch_sync的主要好处是我们可以同时执行操作。