使用dispatch_sync有什么好处? IOS

时间:2014-08-25 10:36:59

标签: ios objective-c grand-central-dispatch

这两种实现之间是否存在差异:

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->调用此函数并定位当前队列会导致死锁

2 个答案:

答案 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的主要好处是我们可以同时执行操作。