0

現在のキューの最後にブロックを追加して、このブロックがキュー内のすべての既存のアイテムの後に呼び出されるようにすることは可能ですか?

以下のコードは機能していないようです。

- (void)someTaskWillBeDoneOnThisThreadLater {
    // The current scope is a delegate method of a library I'm using, 
    // and unfortunately the required task gets executed after this delegate 
    // method is called.

    // wait for current queue to be done with everything, including the current scope
    dispatch_async(dispatch_get_current_queue(), ^{
        // After everything is done, then call the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            // Perform some task on main thread
        });
    });
}

編集:

次のコードは問題を修正しましたが、1 秒の遅延に依存したくありません。私はむしろより良い解決策を見つけます。

dispatch_async(dispatch_get_global_queue(0, 0), ^{

                    dispatch_async(dispatch_get_main_queue(), ^{
                        sleep(1);
                        // Perform something on main thread
                    });
                });
4

3 に答える 3

2

問題は、この作業を行うために専用キューが必要なことだと思います。このコード:

dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSLog(@"FIRST");
    dispatch_async(dispatch_get_current_queue(), ^{
        NSLog(@"LAST");
        dispatch_async(dispatch_get_main_queue(), ^{
            // ...
        });
    });
    sleep(2);
    NSLog(@"SECOND");           
});

与えます:

2012-07-31 22:57:20.005 Objective-C App[22526:1703] FIRST
2012-07-31 22:57:20.009 Objective-C App[22526:2003] LAST
2012-07-31 22:57:22.010 Objective-C App[22526:1703] SECOND

それはあなたが望んでいたものではありません。助けにもdispatch_barrier_asyncなりません。ただし、専用キューを使用する場合:

dispatch_queue_t queue = dispatch_queue_create("test", 0);
dispatch_async(queue, ^{
    NSLog(@"FIRST");
    dispatch_async(queue, ^{
        NSLog(@"LAST");
        dispatch_async(dispatch_get_main_queue(), ^{
            // ...
        });
    });
    sleep(2);
    NSLog(@"SECOND");           
});

あなたが望む結果が得られます:

2012-07-31 23:04:41.882 Objective-C App[22564:1703] FIRST
2012-07-31 23:04:43.887 Objective-C App[22564:1703] SECOND
2012-07-31 23:04:43.889 Objective-C App[22564:1703] LAST

ご覧のとおり、「LAST」が最後に出力され、既にキューにあるブロックが終了するまで 2 秒間待機します。

于 2012-07-31T21:08:16.430 に答える
0

あなたが説明したように実際の問題があるかどうかは明らかではありませんが、これを達成するためにOSX10.7またはiOS4.3から利用できるGCDの機能がありますdispatch_barrier_async()

この関数を使用してブロックをキューに送信すると、そのブロックは、前のすべてのブロックが完了するまで実行を待機します。同様に、後続のすべてのブロックはバリアが完了するのを待ちます。

シリアルキューの性質上、以前に送信されたすべてのブロックが完了するまでブロックの実行が開始されないため、これは同時キューにのみ関連することに注意してください。

于 2012-07-31T21:01:11.590 に答える
0

dispatch_barrier_asyncドキュメントから:

... バリア ブロックがプライベート コンカレント キューの先頭に到達しても、すぐには実行されません。代わりに、キューは現在実行中のブロックの実行が完了するまで待機します。その時点で、バリア ブロックは単独で実行されます。バリア ブロックの後に送信されたブロックは、バリア ブロックが完了するまで実行されません。

したがって、コード内でdispatch_asyncbydispatch_barrier_asyncを置き換えると、必要なことが行われるはずです。

編集:

これは、プライベート (同時) キューでのみ機能します。@Johnnywho の回答と次のコメントも参照してください。

ドキュメントのその部分を見落としていました、申し訳ありません。

于 2012-07-31T20:59:59.177 に答える