私はこれらの2つのアプローチを試しています:
dispatch_async(dispatch_get_main_queue(),^{
[self handleClickAsync];
});
そして
[self performSelector:@selector(handleClickAsync) withObject:nil afterDelay:0];
ボタンの押下に応答して。
2つ目は、UIButton
を期待どおりに強調表示し、次の実行ループでhandleClickAsync
を実行できるようにします(確かに「しばらくしてから」と思います)。 1つ目は、操作が完全に完了するまでUIButton
インスタンスを点灯させません。
GCDでこれを行う正しい方法は何ですか、それともperformSelector
がまだ唯一の方法ですか?
答えはここにあると思います メインディスパッチキューの説明 :
このキューは、アプリケーションの実行ループ(存在する場合)と連携して、キューに入れられたタスクの実行を、実行ループに接続されている他のイベントソースの実行とインターリーブします。
つまり、メインディスパッチキューはセカンダリキューを設定します(メインキューに送信されたブロックを処理するためにUIApplicationMain()
によって提供される標準イベントキューと一緒に。ブロックがキューに存在する場合、実行ループは交互になりますメインイベントキューとディスパッチキューからタスクをデキューします。一方、-performSelector:withObject:afterDelay:
のdelay
パラメータの 参照 は次のことに注意してください。
0の遅延を指定しても、必ずしもセレクターがすぐに実行されるとは限りません。セレクターは引き続きスレッドの実行ループのキューに入れられ、できるだけ早く実行されます。
したがって、実行セレクターを使用すると、操作はメインイベントキューの最後にキューに入れられ、キュー内のその前にあるすべてのものが完了するまで実行されません(おそらく、UIButton
をハイライト解除するコードが含まれます) 処理されました。ただし、メインディスパッチキューを使用すると、ブロックがセカンダリキューに追加され、メインキューに他のブロックがないと想定して、すぐに(つまり、次の実行ループで)処理される可能性があります。この場合、実行ループがセカンダリブロックキューからのイベントを処理している間、ボタンのハイライトを解除するコードはメインイベントキューに残っています。
私はこれがあなたのポイントに当たると思います:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//bla bla bla
}];