Objective-Cにおけるblock循環参照問題の詳細解


ターゲット:block実行中、selfは解放されません。実行したら釈放できます。
最初
blockで直接selfを使うと強い引用になります。

self.myBlock = ^() {
 [self doSomething];
};
またはオブジェクトの属性を使用します。

self.myBlock = ^() {
 NSString *str = _str;
 NSString *str2 = self.str;
};
このような場合、selfはblockを強く引用し、blockもこのオブジェクトを保持し、循環参照をもたらす。
注意したいのは、selfがblockを強く引用する時だけです。一般的にGCDやNSOperationを使用する場合に使用されるインラインブロックは循環参照が発生しません。
weak selfに加入する

__weak __typeof(self) weakSelf = self;
self.myBlock = ^() {
 [weakSelf doSomething];
};
このように、selfはblockを持っていますが、blockはselfに弱い引用であり、循環参照を招くことはありません。
そして、[weakSelf doSomething]過程では、selfは解放されません。完璧です。
でも、もしそうだったら?

__weak __typeof(self) weakSelf = self;
self.myBlock = ^() {
 [weakSelf doSomething];
 [weakSelf doSomething2];
};
[weakSelf doSomething]と[weakSelf doSomething 2]の間で、selfは解放されるかもしれない。これは変な問題を引き起こすかもしれません。
strong selfを追加します

__weak __typeof(self) weakSelf = self;
self.myBlock = ^() {
 __strong __typeof(self) strongSelf = weakSelf;
 [strongSelf doSomething];
 [strongSelf doSomething2];
};
このように、blockはselfを持っていないし、blockは実行中にselfが解放されないことを保証し、本当に最初の目標を達成した。
締め括りをつける
以上はこの文章の全部の内容です。本文の内容は皆さんの学習や仕事に対して一定の参考学習価値を持ってほしいです。ありがとうございます。