2

ループのあるメソッドを含むクラスがあります。特定のイベント (ボタンの押下など) が発生した場合、ループを中断できる必要があります。

NSNotificationCenterボタンが押されたときにループを含むクラスに通知するために を使用しています。

ただし、ループの実行中にボタンを押すと、ループを中断するのではなく、ループが完了した後に通知が発生します。

これは、同じスレッドで動作しているためだと思います。

NSNotificationCenterでは、バックグラウンド/別のスレッドで動作させるにはどうすればよいですか? これは可能ですか?または、それを行うより良い方法はありますか?

4

4 に答える 4

4

通知センターだけではありません。

ループのあるメソッドを含むクラスがあります。特定のイベント (ボタンの押下など) が発生した場合、ループを中断できる必要があります。

そのボタン押下のイベントは、メイン スレッドで受信されます。ループがメイン スレッドで実行されている場合、ループが終了するまでボタンの押下自体は処理されません。通知は、アプリケーションによって実際に処理されるボタンの押下に関連して、すぐに投稿されます。

または、リスト形式で:

  1. ユーザーがボタンを押します。
  2. あなたのループはやるべきことを使い果たし、戻ってきます。
  3. ボタンの押下がアプリケーションに到着し、ボタンによってアクション メッセージに変換されます。
  4. あなたは通知を投稿します。
  5. 通知を受け取ります。

表示されている遅延は、ステップ 1 と 2 の間にあります。ステップ 4 は、ステップ 3 の直後に発生します。

ローカル (分散されていない) NSNotificationCenter の通知は、投稿元のスレッドでディスパッチされるため、アクション メソッドから投稿すると、メイン スレッドでディスパッチされます。これは正常で問題ありません。

通知ではなくループをバックグラウンド スレッド、ディスパッチ キュー、または操作キューに移動します。操作キューを使用する場合、保留中のすべての操作をキャンセルするように操作キューに指示できるため、通知はまったく必要ない場合があります。(操作は、キャンセルされたかどうかを適切な時点で確認する必要があります。前述の理由により、スレッド/操作をランダムに強制終了することは悪い考えです。)

バックグラウンド スレッド、ブロック、および操作は、必要に応じて (たとえば、UI を更新するために) メイン スレッドと通信できます。メイン スレッドの実行ループを介してメッセージを送信するには、 を使用しますperformSelectorOnMainThread:withObject:waitUntilDone:。メイン スレッドでブロックをディスパッチするには、 と を使用dispatch_asyncdispatch_get_main_queueます。メイン スレッドで操作をスケジュールするには、それを に追加し[NSOperationQueue mainQueue]ます。

詳細については、Concurrency Programming GuideNotification Programming Topicsをお読みください。

于 2011-10-27T21:22:25.293 に答える
3

別のスレッドでループを実行します。さらに良いことに、それをNSOperationにして、を呼び出すことができるようにします[.. cancel]performSelectorOnMainThreadNSOperationオブジェクトからUIを更新するときに必ず使用してください。メインスレッドで長時間実行されるループを作成することはお勧めできません。

于 2011-10-27T20:10:46.843 に答える
3

私はあなたのループを別のスレッドで実行し、インスタンス変数を持っていBOOL abort;ますabort = TRUE;.

于 2011-10-27T12:47:01.217 に答える