通知センターだけではありません。
ループのあるメソッドを含むクラスがあります。特定のイベント (ボタンの押下など) が発生した場合、ループを中断できる必要があります。
そのボタン押下のイベントは、メイン スレッドで受信されます。ループがメイン スレッドで実行されている場合、ループが終了するまでボタンの押下自体は処理されません。通知は、アプリケーションによって実際に処理されるボタンの押下に関連して、すぐに投稿されます。
または、リスト形式で:
- ユーザーがボタンを押します。
- あなたのループはやるべきことを使い果たし、戻ってきます。
- ボタンの押下がアプリケーションに到着し、ボタンによってアクション メッセージに変換されます。
- あなたは通知を投稿します。
- 通知を受け取ります。
表示されている遅延は、ステップ 1 と 2 の間にあります。ステップ 4 は、ステップ 3 の直後に発生します。
ローカル (分散されていない) NSNotificationCenter の通知は、投稿元のスレッドでディスパッチされるため、アクション メソッドから投稿すると、メイン スレッドでディスパッチされます。これは正常で問題ありません。
通知ではなくループをバックグラウンド スレッド、ディスパッチ キュー、または操作キューに移動します。操作キューを使用する場合、保留中のすべての操作をキャンセルするように操作キューに指示できるため、通知はまったく必要ない場合があります。(操作は、キャンセルされたかどうかを適切な時点で確認する必要があります。前述の理由により、スレッド/操作をランダムに強制終了することは悪い考えです。)
バックグラウンド スレッド、ブロック、および操作は、必要に応じて (たとえば、UI を更新するために) メイン スレッドと通信できます。メイン スレッドの実行ループを介してメッセージを送信するには、 を使用しますperformSelectorOnMainThread:withObject:waitUntilDone:
。メイン スレッドでブロックをディスパッチするには、 と を使用dispatch_async
しdispatch_get_main_queue
ます。メイン スレッドで操作をスケジュールするには、それを に追加し[NSOperationQueue mainQueue]
ます。
詳細については、Concurrency Programming GuideとNotification Programming Topicsをお読みください。