1. ホーム
  2. iphone

[解決済み] NSOperationQueueが全タスクを終了したら通知を受ける

2023-02-19 01:31:34

質問

NSOperationQueuewaitUntilAllOperationsAreFinished がありますが、同期的に待ちたいわけではありません。キューが終了したら、UIにプログレスインジケータを隠したいだけなのです。

これを達成するための最良の方法は何でしょうか?

私は、自分の NSOperation からの通知は、どれが最後になるかわからないし [queue operations] は、通知を受け取ったときにまだ空でない (あるいはもっと悪いことに再入力される) かもしれないからです。

どのように解決するのですか?

KVOを使用して operations プロパティをチェックすることで、キューが完了したかどうかを知ることができます。 [queue.operations count] == 0 .

KVOを行うファイルのどこかで、KVOのためのコンテキストを次のように宣言します ( 詳細情報 ):

static NSString *kQueueOperationsChanged = @"kQueueOperationsChanged";

キューをセットアップするときは、こうしてください。

[self.queue addObserver:self forKeyPath:@"operations" options:0 context:&kQueueOperationsChanged];

そして、これを observeValueForKeyPath :

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
                         change:(NSDictionary *)change context:(void *)context
{
    if (object == self.queue && [keyPath isEqualToString:@"operations"] && context == &kQueueOperationsChanged) {
        if ([self.queue.operations count] == 0) {
            // Do something here when your queue has completed
            NSLog(@"queue has completed");
        }
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object 
                               change:change context:context];
    }
}

(これは、あなたの NSOperationQueue という名前のプロパティに queue )

オブジェクトが完全に解放される前のある時点で(またはキューの状態を気にしなくなった時点で)、このようにKVOから登録を解除する必要があります。

[self.queue removeObserver:self forKeyPath:@"operations" context:&kQueueOperationsChanged];



追記:iOS 4.0には NSOperationQueue.operationCount プロパティがあり、ドキュメントによると、KVO に準拠しています。しかし、この回答は iOS 4.0 でも動作するため、後方互換性のためにまだ役に立ちます。