28

私はこれらの2つのアプローチを試みています:

dispatch_async(dispatch_get_main_queue(),^{
    [self handleClickAsync];
});

[self performSelector:@selector(handleClickAsync) withObject:nil afterDelay:0];

ボタンを押したときの反応。

2番目は、次の実行ループでUIButton期待どおりに強調表示して実行することを可能にしhandleClickAsyncます(確かに「いつか後で」と思います)。UIButton1 つ目は、操作が完全に完了するまでインスタンスを点灯させません。

GCDでこれを行う正しい方法は何performSelectorですか?それとも唯一の方法ですか?

4

2 に答える 2

44

答えは、メインのディスパッチ キューの説明にあると思います。

このキューは、アプリケーションの実行ループ (存在する場合) と連携して、キューに入れられたタスクの実行と、実行ループに接続されている他のイベント ソースの実行をインターリーブします。

つまり、メイン ディスパッチ キューは、セカンダリ キューを設定します (UIApplicationMain()メイン キューにサブミットされたブロックを処理するために によって提供される標準のイベント キューと並んで)。ブロックがキューに存在する場合、実行ループはメイン イベント キューからタスクを交互にデキューします。とディスパッチ キュー一方、パラメーターのリファレンスは、次の点に注意してください。delay-performSelector:withObject:afterDelay:

遅延を 0 に指定しても、セレクターがすぐに実行されるとは限りません。セレクターは引き続きスレッドの実行ループでキューに入れられ、できるだけ早く実行されます。

したがって、実行セレクターを使用すると、操作はメイン イベント キューの最後にキューに入れられ、キュー内の前にあるすべての操作 (おそらく の強調表示を解除するコードを含むUIButton) が処理されるまで実行されません。ただし、メイン ディスパッチ キューを使用すると、ブロックがセカンダリ キューに追加され、メイン キューに他のブロックがないと仮定して、すぐに (つまり、次の実行ループで) 処理される可能性があります。この場合、実行ループがセカンダリ ブロック キューからのイベントを処理している間、ボタンのハイライトを解除するコードはまだメイン イベント キューに置かれています。

于 2012-05-04T14:30:53.303 に答える
27

これはあなたの要点に達すると思います:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
     //bla bla bla
}];
于 2012-12-27T06:13:36.660 に答える