私はしばらくブロックを扱ってきましたが、漏れの可能性のあるすべてのシナリオを認識しようとしています。「リテイン サイクル ループ」についてはよく読みましたが、他にも考えられるシナリオがあるのではないかと思います。また、次のようないくつかの単純なケースで考えています。ブロック内でブロックを呼び出すとどうなりますか?; ARC を使用する場合と使用しない場合で、ブロック メモリの管理は異なりますか?; ブロックが計測器 (または他のツール) でメモリ リークしているかどうかを確認する方法は?
1 に答える
簡単な答え: ブロックは本質的に特別なリークの問題を引き起こしません (以下で説明する特別な状況での保持サイクルを除く)。
長い答え: いくつかの考え:
保持サイクル ( ARCでは強い参照サイクルとも呼ばれます) を除いて、ブロックに関連する特別なリーク リスクはありません。ブロックが参照するオブジェクトへの強力な参照を保持していることを覚えている場合は、メモリ管理の標準的な基本ルールに従ってください。
Use Lifetime Qualifiers to avoid strong reference cycles で説明したように、MRC では修飾子を使用して
__block
これらの強い参照サイクルを解決できますが、ARC では__weak
修飾子を使用できます。ブロック内にブロックを配置している場合、追加のリーク リスクは発生しません (ブロック内でブロックを実行する場合に一般的に起こりにくい、強力な参照サイクルを引き起こす循環参照セットを作成しない限り)。
__block
ブロックは参照するオブジェクトを保持します ( MRC や__weak
ARCなどでオブジェクトが修飾されていない限り)。ブロックを使用するという事実は、コードがリークするかどうかには関係ありません。これは、ARC と MRC の選択と、保持サイクルを回避したかどうか、および MRC を実行する場合は必要なrelease
ステートメントを含めたかどうかの機能です。リークを見つけるという点では、標準ツールはすべて正常に機能します。
特に ARC 以外のコードを実行する場合は、静的アナライザー ( shift+ command+Bまたは [製品] メニューから [分析] を選択) が非常に便利です。
Instruments User GuideのFinding Leaks in Your Appディスカッション。
強力な参照サイクルの場合、インストゥルメントの Leaks ツールによって常にフラグが立てられるとは限りません。その時点で、Instruments の Allocations ツールを使用して、解放されているはずなのに解放されていないと思われる割り当てを強調表示すると、そのメモリを割り当てたものが表示されると便利な場合があります。ARC を使用した iOS アプリを参照し、オブジェクトの所有者を特定する
一部のオブジェクトが適切に割り当て解除されているかどうか疑問に思っている場合は、解放する
dealloc
必要があるオブジェクトに診断実装を追加すると便利です。- (void)dealloc { NSLog(@"%s", __FUNCTION__); // if non-ARC, remember to include the following line, too: // // [super dealloc]; }
そうすれば、オブジェクトの割り当てが解除されると、コンソールにメッセージが表示されます。
リークが心配な場合、ARC を使用することは (IMHO) 多くのありふれたリークを排除する最も簡単な方法の 1 つです。
release
ARC 以外のコードでは、 orを単純に省略してリークするのは信じられないほど簡単autorelease
です (ただし、確かに、上記のリンクはそれらを見つけるのに役立ちます)。単純な「ああ、忘れていた」という理由で、ARC でリークするのははるかに困難release
です。
参考文献
Objective-C を使用したプログラミングガイドの「ブロックの操作」セクション