iOSにはバージョン5.0からARCメカニズムが追加されましたが、複雑な相互参照によりメモリーリークが発生する可能性があります。そのため、原理を理解することが重要です。
ここでは、Instrumentsを使用して、ARCを使用せずにプログラムのメモリ・リークを見つける方法と、NSZombieEnabled設定の使用方法について説明します。
この記事は、あなたがすでにObj-Cのメモリ管理メカニズムに比較的精通していることを前提としています。
実験的開発環境:XCode 4.5.2
1.デモを実行します。
まず、準備されたメモリー・leak app実装したデモをダウンロードしてみましょう。
ダウンロードして開いて実行すると、プログラムは寿司のリストで、様々な巻き寿司がリストアップされています。行目を選択したところでクラッシュしました。クラッシュのスクリーンショット:
クラッシュした場所で止まってしまい、クラッシュの場所はわかっていますが、クラッシュの正確な原因はわかりません。
2、NSZombieEnabledを設定
これは "EXC_BAD_ACCESS "エラーです。XCodeのオプション "NSZombieEnabled "をオンにしてください。クラッシュの場合、もう少しヒントが得られるかもしれません。
セットアップ手順:1
2: 赤いボックスにチェックを入れてください。
もう一度クラッシュし、今度は出力ウィンドウに追加のエラー・メッセージが表示されます:
つまり、解放されたメモリにメッセージを送るということです。つまり、解放されたメモリを使うということで、C言語では「ワイルド・ポインタ」を使うことに相当します。
クラッシュからこのステートメントを見ると、sushiStringはstringWithFormatから初期化されているので問題ないはずです。これが_lastSushiSelectedの問題です。
- </span>
現時点では動作し、クラッシュすることはありません。
3.メモリリークの分析
アプリがクラッシュしなくなったので、メモリリークがあるかどうか確認してください。XCodeのAnalyzeを使えば、メモリリーク箇所を分析できます!
分析してみるとわかります:
alertViewがリリースされておらず、メモリリークがあります。
[alertViewリリース]。
再解析すれば、この問題は解決。
4.インストゥルメンツのリークツールの使用
6、メモリリークの解決
tableView:didSelectRowAtIndexPath について、そのメモリプロシージャを解析してください:
- sushiString変数はautoreleaseによって作成され、その参照カウントは1です。
- このメソッドが終了すると、sushiStringの自動解放が有効になり、この変数の参照カウントは1になります。
- tableView:didSelectRowAtIndexPathメソッドが再度実行されると、_lastSushiSelectedには新しいポインタが割り当てられ、古い_lastSushiSelectedの参照カウントは1のまま解放されず、メモリリークが発生します。
どうすれば解決できますか?
- [_lastSushiSelected release];
- _lastSushiSelected = [sushiString retain].
について: tableView:cellForRowAtIndexPath
- NSString *sushiString = [NSString stringWithFormat:@"%d: %@", indexPath.row, sushiName];
この時点で、もう一度クリック、ドラッグ、操作してみると、メモリーリークはなくなっています。メモリリークがブロックされていることがわかります。




