9

更新操作を処理するキューに入れられたブロックを再スケジュールしようとしています。主な目標は、最小限の(UI更新要求)でUIオブジェクト(オンラインユーザーテーブル...)を更新することです。(サーバーは時々大量の更新を雨に降らせます、イェーイ!)

簡単にするために、主なシナリオは次のとおりです。

  • dispatch_queue_tインスタンス(特定のUI更新ブロックを処理するキュー)は、シリアルディスパッチキュー(プライベートディスパッチキュー)です。

  • 操作(UI更新ブロック)は、dispatch_afterでt時間でスケジュールされます(データセットの更新ごとに更新する代わりに、t時間以内に更新要求を収集し、それらに対して単一のUI更新を実行します)

  • データセットが更新された場合は、スケジュールされたイベントがすでに存在するかどうかを確認してください。はいの場合、dispatch_queue_tインスタンスからスケジュールを解除します。次に、同じブロックをt時間の遅延で再スケジュールします。

また;

tは、ユーザーが気付かない可能性のある短い時間間隔です(500ミリ秒など)。別のアプローチを歓迎します。

この背後にある私の動機。

私はAndroidのハンドラー(Runnableインスタンスとのpost&removeCallbacksの組み合わせ)を介して同じロジックを適用しましたが、iOSでも同じことを達成できることを願っています。

編集:

@Svenが提案したように、NSOperationQueueの使用は、各NSOperationのキャンセルをサポートしているため、シナリオにより適しています。私は文書をざっと読んで見つけました。

操作のキャンセル操作キューに追加されると、操作オブジェクトはキューによって実質的に所有され、削除することはできません。操作をデキューする唯一の方法は、操作をキャンセルすることです。単一の個別の操作オブジェクトをキャンセルメソッドを呼び出すことによってキャンセルするか、キューオブジェクトのcancelAllOperationsメソッドを呼び出すことによってキュー内のすべての操作オブジェクトをキャンセルすることができます。

操作が不要になったことが確実な場合にのみ、操作をキャンセルする必要があります。キャンセルコマンドを発行すると、操作オブジェクトが「キャンセル」状態になり、実行されなくなります。キャンセルされた操作は引き続き「終了」したと見なされるため、それに依存するオブジェクトは、その依存関係をクリアするための適切なKVO通知を受け取ります。したがって、操作を選択的にキャンセルするのではなく、アプリケーションの終了やユーザーがキャンセルを具体的に要求するなどの重要なイベントに応答して、キューに入れられたすべての操作をキャンセルする方が一般的です。

4

2 に答える 2

14

これはGCDでも簡単に実行でき、ここでNSOperationQueueである大きなハンマーに手を伸ばす必要はありません。

代わりに、繰り返しのないディスパッチタイマーソースを直接使用してdispatch_afterください(これは、このようなタイマーソースの便利なラッパーであり、タイマーがオフになるまで実際にはブロックをキューにエンキューしません)。

保留中のタイマーソースの実行を。で再スケジュールできますdispatch_source_set_timer()

于 2013-02-21T20:28:19.553 に答える
6

ディスパッチキューにエンキューされている操作を削除したり、変更したりすることはできません。NSOperationQueue代わりに、キャンセルをサポートするより高いレベルを使用してみてください。

于 2013-02-21T15:45:19.847 に答える