1

看看这段代码:

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,而且永远不会走得更远。程序刚刚停止。谁能解释为什么它会这样?幕后发生了什么让它停止?

4

3 回答 3

3

如果您从主队列(我假设)运行此代码,则会出现死锁。主队列被阻塞,直到您从第一次调用到dispatch_sync完成的阻塞。但是在这个块内,您等待另一个块在主队列上完成,由于主队列是串行队列,因此在外部块完成之前无法执行。

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

于 2013-02-16T13:40:23.783 回答
2

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

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

您似乎正在尝试:

  1. 在另一个队列上做一些工作
  2. 更新用户界面
  3. 继续在另一个队列上做更多的工作

如果那是正确的,您可能想要使用 NSOperation ...

于 2013-02-16T13:52:15.363 回答
2

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

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

于 2013-02-16T14:03:26.133 回答