为什么此代码会停止程序执行?

时间:2013-02-16 13:31:22

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

看看这段代码:

dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, nil), ^
{
    NSLog(@"DISPATCH_QUEUE");//executed

   //never goes further
    dispatch_sync(dispatch_get_main_queue(), ^
                   {
                       NSLog(@"MAIN_QUEUE");
                   });

    NSLog(@"END OF DISPATCH QUEUE");
});

我希望这段代码能像往常一样运行,但它总是放在控制台字DISPATCH_QUEUE中,而且永远不会更进一步。该计划刚刚停止。任何人都可以解释为什么它这样做?幕后发生了什么让它停止了?

3 个答案:

答案 0 :(得分:3)

如果从主队列(我假设)运行此代码,则此处存在死锁。主队列被阻止,直到第一次调用dispatch_sync的阻止完成为止。但是在这个块中你等待另一个块在主队列上完成,直到外部块完成后才能执行,因为主队列是一个串行队列。

您需要将其中一个调用更改为dispatch_async

答案 1 :(得分:2)

你可能遇到了僵局;假设您对dispatch_sync的第一次调用来自主线程。

在这种情况下,主线程正在等待第一次调度完成,但在该块内,您正在尝试调度回主线程...死锁。

看来你正试图:

  1. 在另一个队列上做一些工作
  2. 更新用户界面
  3. 继续在其他队列上做更多的工作
  4. 如果这是对的,你可能想要使用NSOperation ......

答案 2 :(得分:2)

dispatch_sync在给定队列上运行一个块并等待它完成。在这种情况下,队列是主调度队列。主队列以FIFO(先进先出)顺序在主线程上运行其所有操作。这意味着无论何时调用dispatch_sync,您的新块都将放在该行的末尾,并且在队列中的其他所有内容完成之前不会运行。

这里的问题是你刚入列的块是在等待在主线程上运行的行的末尾,但可能你的上面的代码当前正在主线程上运行。在当前方法使用主线程完成之前,队列末尾的块无法访问主线程。所以只有dispatch_async在这里工作。