2

私はiOSでいくつかのカスタマイズを行っています.メソッドを非同期的に実行するシステムクラスをサブクラス化しています(おそらくdispatch_asyncを使用) サンプルコード:

-(void)originalAsyncMethod {
    [super originalAsyncMethod];
    dispatch_async(dispatch_get_main_queue(), ^{
      //do something that needs to happen just after originalAsyncMethod finishes executing
    });
  }

非同期スーパー メソッドが実行された後にカスタム コードが確実に実行されるようにする方法はありますか?

4

1 に答える 1

2

あなたの質問に基づいてこれが可能かどうかはわかりませんが、スーパーの実装に直接アクセスできる場合、これを達成するのは難しくありません。

まず、スーパー クラスにアクセスでき、スーパー実装も非同期でメイン キューにディスパッチされると仮定すると、期待どおりに動作させるために実際に何もする必要はありません。使用するときdispatch_get_main_queue()は、FIFO (先入れ先出し) 順で実行されるメイン スレッドのシリアル キューの最後にディスパッチ ブロックを追加します。

2 番目のオプションも、タスクを実行する独自のディスパッチ キューを手動で作成する必要があるため、スーパー実装へのアクセスに大きく依存しています。言うまでもなく、シリアル ディスパッチ キューを使用すると、このキューで FIFO の順序付けがdispatch_get_main_queue()行われ、メイン スレッドで実行する必要がなくなります。

私が考えることができる最後のオプションは、必ずしもスーパークラスを変更する必要はありませんが、スーパーが実行されているキューを知る必要があります。(グローバル キューの場合はまだ正しく動作しない可能性があります) dispatch_barrier を使用することで、サブクラスのディスパッチ ブロックも (dispatch_barrier を介して) キューに追加されていることを認識して、並行キューでスーパー実装を非同期に実行できます。スーパーディスパッチ(およびキューへの他の以前の送信)が完了すると実行されます。

ドキュメントの引用

ディスパッチ バリアを使用すると、同時ディスパッチ キュー内に同期ポイントを作成できます。バリアに遭遇すると、コンカレント キューは、バリア ブロックの実行が完了する前に送信されたすべてのブロックが実行されるまで、バリア ブロック (またはそれ以降のブロック) の実行を遅らせます。その時点で、バリア ブロックは単独で実行されます。完了すると、キューは通常の実行動作を再開します。

于 2013-08-19T14:17:32.997 に答える