1

ブロックに弱い参照であるプロパティを持つクラスがあります。私はこのように、このブロックを使用して、クラス内の別のポイントで"self"をキャプチャするときに弱く保持されたブロックが保持サイクルを引き起こす方法

@interface BlockTest : NSObject 
    @property (nonatomic, weak) void(^testBlock)(); 
@end 

- (void)foobar { 
    self.testBlock = ^{ 
     [self doSomething]; 
    }; 
} 

コンパイラ(アップルLLVM 3.0)selfが強く、ここで捕獲されているため、保持サイクルがあるかもしれないと文句を言います。しかし、ブロック自体が__weakの参照であるため、これが保持サイクルにどのようにつながるのか分からないので、うまくいくはずです。私がARCの弱い参照を正しく理解していれば、-foobarメソッドが返されたときに、self.testBlockに渡されたブロックは解放されなければならず、そうでなければselfを解放しなければなりません。

コンパイラーがまだ保持サイクルがあると思われる理由は何ですか?

+0

あなたが持っているセットアップはかなり役に立たないです。ブロックは、関数への強い参照がないので、関数が終了した直後に割り当てが解除されます。プロパティは 'nil'になります。 – newacct

+0

それは普遍的には当てはまりません。グローバルブロックとスタックブロックは保持または解放されないため、割り当て後も有効です(スタックブロックの場合は現在のスコープの終わりまで)。これは単なるサンプルです。アイデアはブロックを何かの周りに保つことではありませんでした。 IIRC私がこの質問をしたとき、私は警告をトリガーせずに 'self'というメソッドのコールバックブロックに' self'を取り込む方法を探していました。 – Alfonso

答えて

8

ブロックは、ブロック自体の参照方法に関係なく、ブロック内のオブジェクトを強くキャプチャします。保持サイクルの警告はそれだけで、可能性の警告です。アプリのコンテキストに基づいて、このサイクルで保持サイクルが発生しないことが分かっている場合は、無視しても問題ありません。次のように警告を取り除くために、あなたは、強いまたは弱い、仲介者を通じて自己を渡すことができます。

__weak typeof(self) weakSelf = self; 
self.testBlock = ^{ 
    [weakSelf doSomething]; 
}; 

私は強い参照することと上記の操作を行うためにあなたのブロックのプロパティを変更すると思います。

+0

さて、私はこれを避けることができたと思ったが、それは見えるようにこれが行く方法です。ありがとう! – Alfonso