2

次のコードを調べて、ARC でコンパイルされたと仮定します。

- (無効) フー {
    NSOperationQueue *oq = [[NSOperationQueue alloc] init];
    [oq addOperationWithBlock:^{
        // ここで長時間実行オペレーションがあると仮定します。
    }];
}

操作キューはローカル変数として宣言されていますが、実行中の操作がある限り、その有効期間はメソッドのスコープを超えて続きます。

これはどのように達成されますか?

アップデート:

Rob Mayoff のよく考え抜かれたコメントには感謝していますが、私の質問が正しくなかったと思います。NSOperationQueue に関する具体的な質問ではなく、ARC でのオブジェクトの有効期間に関する一般的な質問です。具体的には、私の質問はこれです:

ARC の下で、オブジェクトはどのようにして自身のライフタイムの管理に参加できるのでしょうか?

私は非常に長い間プログラマーをしており、そのようなことの落とし穴をよく知っています。私は、これが良いアイデアなのか悪いアイデアなのかについて説教されるつもりはありません。一般的にはダメだと思います。むしろ、私の質問は学術的なものです。それが良いアイデアか悪いアイデアかは関係ありませんが、ARC でこれを行う方法と、そのための具体的な構文は何ですか?

4

4 に答える 4

3

以下にいくつかの可能性を示します。

  1. NSOperationQueue空になるまで保持され、空になると解放されます。

  2. これNSOperationQueueにより、他のオブジェクトがそれを保持します。たとえば、NSOperationQueueGCD を使用しているため、おそらくaddOperationWithBlock:次のようになります。

    - (void)addOperationWithBlock:(void (^)(void))block {
        void (^wrapperBlock)(void) = ^{
            block();
            [self executeNextBlock];
        };
        if (self.isCurrentlyExecuting) {
            [self.queuedBlocks addObject:wrapperBlock];
        } else {
            self.isCurrentlyExecuting = YES;
            dispatch_async(self.dispatchQueue, wrapperBlock);
        }
    }
    

    そのコードでは、wrapperBlockには への強い参照が含まれているNSOperationQueueため、(ARC を想定して) は保持されますNSOperationQueue。(realaddOperationWithBlock:はスレッドセーフであり、複数のブロックの同時実行をサポートしているため、これよりも複雑です。)

  3. メソッドの範囲を超えてNSOperationQueue 存在しません。fooおそらく、addOperationWithBlock:戻るまでに、長期実行ブロックはすでに GCD キューに送信されています。への強い参照を保持していないため、割り当てを解除してはならないoq理由はありません。oq

于 2012-05-07T22:42:30.930 に答える
0

私が考えることができる最も簡単なことは、オブジェクトがそれ自体を追加および削除するグローバル NSMutableArray (またはセットなど) を持つことです。別のアイデアは、(すでに認めたように)奇妙にメモリ管理されたコードを非ARCファイルのカテゴリに配置し、-retainと-releaseを直接使用することです。

于 2012-05-08T04:57:01.810 に答える