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終了するまで、メイン キューはブロックされます。ただし、このブロック内では、メイン キューがシリアル キューであるため、外側のブロックが終了するまで実行できないメイン キューで別のブロックが終了するのを待ちます。

への呼び出しの 1 つを変更する必要がありますdispatch_async

于 2013-02-16T13:40:23.783 に答える
2

dispatch_sync指定されたキューでブロックを実行し、完了するのを待ちます。この場合、キューはメインのディスパッチキューです。メインキューは、メインスレッドですべての操作をFIFO(先入れ先出し)の順序で実行します。つまり、dispatch_syncを呼び出すと、新しいブロックは行の最後に配置され、キュー内の他のすべてが完了するまで実行されません。

ここでの問題は、キューに入れたばかりのブロックがメインスレッドで実行されるのを待っている行の終わりにあることですが、おそらく上記のコードは現在メインスレッドで実行されています。キューの最後にあるブロックは、現在のメソッドがメインスレッドの使用を終了するまで、メインスレッドにアクセスできません。したがって、ここでのみdispatch_async機能します。

于 2013-02-16T14:03:26.133 に答える
2

おそらくデッドロック状態になっているでしょう。dispatch_syncへの最初の呼び出しがメインスレッドからのものであると仮定します。

その場合、メイン スレッドは最初のディスパッチが終了するのを待っていますが、そのブロック内では、メイン スレッドにディスパッチしようとしています... デッドロック。

あなたがしようとしているようです:

  1. 別のキューで何らかの作業を行う
  2. UIを更新する
  3. その他のキューでさらに作業を続けます

そうであれば、おそらく NSOperation を使用したいと思うでしょう...

于 2013-02-16T13:52:15.363 に答える