1

ブロック内で弱い参照を強い参照に渡すと、なぜ機能するのですか? ブロック内のローカル変数が保持されている場合、保持が追加され、selfこの悪い保持サイクルが作成されますか?

例は次のとおりです。

__weak id weakSelf = self; 
[self.operationQueue addOperationWithBlock:^{
    NSNumber* result = findLargestMersennePrime();
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
        MyClass* strongSelf = weakSelf; 
        strongSelf.textLabel.text = [result stringValue];
    }]; 
}];
4

2 に答える 2

3

ブロックを作成またはコピーすると (たとえば、gcd にスケジュールするときにコピーされる可能性があります)、参照された変数がキャプチャされます (__block 指定子で宣言されていない場合)。強い参照は保持されますが、弱い参照は保持されません。

ローカルstrongSelf変数を作成すると、ブロックが実行されている間(つまり、実行されずにプロパティに置かれている間は強い参照はありません)、その変数はself生き続けます。直接参照すると -がキャプチャされて保持されますが、ブロックが生きている間保持されるようになりました。selfselfself

__weak id weakSelf = self; 
[self.operationQueue addOperationWithBlock:^{
    NSNumber* result = findLargestMersennePrime();
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 

        MyClass* strongSelf = weakSelf; // strong reference when block executes
        [self foo]; // strong reference when block created/copied

        strongSelf.textLabel.text = [result stringValue];
    }]; 
}];

違いを見ます?直接参照を使用してオブジェクトへのすべての強力なポインターを削除してselfも、ブロック内にはまだ 1 つの強力な参照があり、それはキャプチャされて保持されたものです。同時に、ローカルポインターはブロックが実行されている間strongSelfのみ強い参照を保持するため、既に死んでいる場合はnil になり、nil 値を取得します。selfselfweakSelfstrongSelf

于 2014-11-11T15:38:07.717 に答える
1

いいえ、自己が強くキャプチャされていないため、サイクルは作成されません! :)

strongSelf は自己を保持する強い参照ですが、strongSelf はローカル変数であるため、ブロックが完了すると解放され、保持カウントが正常に低下します

于 2014-11-11T15:26:24.090 に答える