UIレスポンシブのバックグラウンドで一連のNSXMLDocumentsをダウンロードして解析するNSInvocationOperationがあります。
呼び出し操作を停止しようとする試みは、NSOperationQueue の cancelAllOperations を呼び出すことです。しかし、これは呼び出しの実行を停止しないようです。
この問題にどう対処するかについてのアイデアはありますか?
UIレスポンシブのバックグラウンドで一連のNSXMLDocumentsをダウンロードして解析するNSInvocationOperationがあります。
呼び出し操作を停止しようとする試みは、NSOperationQueue の cancelAllOperations を呼び出すことです。しかし、これは呼び出しの実行を停止しないようです。
この問題にどう対処するかについてのアイデアはありますか?
更新:これを行うと、Instrumentsはリークを大量に表示します。注意して進んでください!私が実際に何かに取り組んでいて、他の誰かがリークのハードルを乗り越える方法を理解できる場合に備えて、これをここに保持しています。
これがねじれたアイデアです。これを入力するときに再試行します。
NSInvocationOperationのinitWithTarget: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を強制できる場合、これが実際に機能するかどうかがわかります。:)
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はそれをチェックして、必要に応じてキャンセルできます。
上記の投稿は素晴らしいですが、元の質問にもっと直接的に答えるには、キャンセルをサポートしていないため、NSInvocationOperation オブジェクトを停止できないようです。サブクラス化する必要があります。