私が持っていたクラスのスライドから、あなたが直面している可能性のあるメモリサイクルの問題について説明しました。
クラスの次のプロパティがある場合はどうなりますか?
@property (strong, nonatomic) NSArray* myBlocks; // array of blocks
次に、そのクラスのメソッドの1つで次のことを実行しようとしましたか?
[self.myBlocks addObject:^() {
[self doSomething];
}];
ブロック内で参照されるすべてのオブジェクトは、ブロックが保持している限り、ヒープ内に留まります。(言い換えると、ブロックは、ブロック内で参照されるすべてのオブジェクトへの強力なポインターを保持します。)
この場合、selfはこのブロックで参照されるオブジェクトです。したがって、ブロックには自己への強力なポインタがあります。ただし、selfにもブロックへの強力なポインタがあることに注意してください(myBlocksプロパティを介して)
これは深刻な問題です!
現在、自己もブロックもヒープから逃れることはできません。それは、それらの両方(互いのポインター)への強力なポインターが常に存在するためです。これはメモリの「サイクル」と呼ばれます。
解決:
ローカル変数は常に強力です。それは大丈夫です。スコープから外れると消えて、強いポインタが消えてしまうからです。しかし、ローカル変数が弱いことを宣言する方法があります。方法は次のとおりです...
__weak MyClass* weakSelf = self;
[self.myBlocks addObject:^{
[weakSelf doSomething];
}];
これで問題が解決します。これは、ブロックに自分自身への弱いポインタしかないためです。(自己はまだブロックへの強力なポインターを持っていますが、それは大丈夫です)大学の誰かがこの自己への強力なポインターを持っている限り、ブロックのポインターは良いです。そして、自己が存在しない場合(myBlocksが存在しないため)、ブロックは存在しないため、すべてが順調です。