9

UIレスポンシブのバックグラウンドで一連のNSXMLDocumentsをダウンロードして解析するNSInvocationOperationがあります。

呼び出し操作を停止しようとする試みは、NSOperationQueue の cancelAllOperations を呼び出すことです。しかし、これは呼び出しの実行を停止しないようです。

この問題にどう対処するかについてのアイデアはありますか?

4

4 に答える 4

11

更新:これを行うと、Instrumentsはリークを大量に表示します。注意して進んでください!私が実際に何かに取り組んでいて、他の誰かがリークのハードルを乗り越える方法を理解できる場合に備えて、これをここに保持しています。

これがねじれたアイデアです。これを入力するときに再試行します。

NSInvocationOperationinitWithTarget:selector:object:メソッドのオブジェクトとして操作を設定します。すでにNSOperationQueueがあると仮定します(これをキューと呼びます)。

NSInvocationOperation *operation = [NSInvocationOperation alloc];
operation = [operation initWithTarget:self selector:@selector(myOperation:) object:operation];
[queue addOperation:operation];
[operation release];

allocを独自の呼び出しに分割する必要があることに注意してください。そうしないと、オブジェクト操作に設定できません。

次に、操作メソッド内で、オブジェクトをキャストバックし、必要に応じてisCancelledのチェックを振りかけます。例えば:

  - (void)myOperation:(id)object {
    NSInvocationOperation *operation = (NSInvocationOperation *)object;
    if ([operation isCancelled]) return;
    ...
  }

ここでオブジェクトを渡すので、セレクターがinitWithTarget:...呼び出しでコロンで終わっていることを確認してください。

ここまでは順調ですね。これで、 cancelAllOperationsを強制できる場合、これが実際に機能するかどうかがわかります。:)

于 2009-08-11T21:03:42.130 に答える
8

NSInvocationOperationisCancelledがYESであるかどうかを確認する必要があります。NSInvocationOperationでこれを行うには、KeyValueObservingを使用できます。

操作の実行時に、オブジェクトをNSInvocationOperationisCancelledオブザーバーとして追加します。

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:<targetObj> selector:@selector(<targetMethod>) object:nil];
[operation addObserver:<targetObj> forKeyPath:@"isCancelled" options:NSKeyValueObservingOptionNew context:nil];
[operQueue addOperation:operation];
[operation release];

次に、targetObjで実装します

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

NSOperationQueueのcancellAllOperationsによって変更されるisCancelledを監視します。ここでプライベートフラグを設定でき、targetMethodはそれをチェックして、必要に応じてキャンセルできます。

于 2010-06-02T11:16:11.113 に答える
5

上記の投稿は素晴らしいですが、元の質問にもっと直接的に答えるには、キャンセルをサポートしていないため、NSInvocationOperation オブジェクトを停止できないようです。サブクラス化する必要があります。

于 2009-05-01T20:39:38.493 に答える