blog

Xcodeとインストゥルメント・デバッグでiOSのメモリ・リークを解決する

iOS 5.0以降、ARCメカニズムが追加されましたが、相互参照関係の複雑さにより、メモリリークはまだ存在する可能性があります。そのため、原理を理解することが重要です。ここでは、ARCを使わないプログ...

Jun 28, 2015 · 4 min. read
シェア

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の問題です。

  1. </span>

現時点では動作し、クラッシュすることはありません。

3.メモリリークの分析

アプリがクラッシュしなくなったので、メモリリークがあるかどうか確認してください。XCodeのAnalyzeを使えば、メモリリーク箇所を分析できます!

分析してみるとわかります:

alertViewがリリースされておらず、メモリリークがあります。

[alertViewリリース]。

再解析すれば、この問題は解決。

4.インストゥルメンツのリークツールの使用

メモリ・リークの分析では、すべてのメモリ・リークをチェックすることはできません。 メモリ・リークの中には、ユーザーが操作している実行時に発生するものもあります。そこでInstrumentsの出番です。
上記の操作によると、ビルドが正常に飛び出す楽器ツールの後、リークオプションを選択し、今回は寿司プログラムも実行している、リスト内の項目を選択し、ドラッグなどの操作の後、ツールは、次の結果が表示されます:
お察しの通り、赤いバーはメモリリークを示しています。このツールでリーク箇所を確認するには?
ツールバーの赤い丸いボタンを押して、メモリアクティビティを監視するツールを停止します。Leak]を選択し、中央の十字をタップして[Call Tree]を選択します。
この時点でメモリ・リークの具体的なコードが見つかり、右側の赤枠でどのメソッドにメモリ・リークがあるかが特定されます。
これらのメソッドをダブルクリックするだけで、特定のコードにジャンプします。
これが100%メモリがリークするヒントになるはずです。

6、メモリリークの解決

問題が見つかりました。

tableView:didSelectRowAtIndexPath について、そのメモリプロシージャを解析してください:

  1. sushiString変数はautoreleaseによって作成され、その参照カウントは1です。
  2. このメソッドが終了すると、sushiStringの自動解放が有効になり、この変数の参照カウントは1になります。
  3. tableView:didSelectRowAtIndexPathメソッドが再度実行されると、_lastSushiSelectedには新しいポインタが割り当てられ、古い_lastSushiSelectedの参照カウントは1のまま解放されず、メモリリークが発生します。

どうすれば解決できますか?

  1. [_lastSushiSelected release];  
  2. _lastSushiSelected = [sushiString retain].

について: tableView:cellForRowAtIndexPath

[cpp]プレインコピーを 表示
  1. NSString *sushiString = [NSString stringWithFormat:@"%d: %@", indexPath.row, sushiName];  

この時点で、もう一度クリック、ドラッグ、操作してみると、メモリーリークはなくなっています。メモリリークがブロックされていることがわかります。

Read next

RSA 2014:セキュリティ専門家たちは、パブリック・クラウドにデータを保管するのは安全だという意見で一致している

マイクロソフト、グーグル、その他のクラウドベンダーのセキュリティ専門家は、今週サンフランシスコで開催されたRSA 2014カンファレンスのパネルディスカッションでこのテーマについて議論しました。各ベンダーは、顧客がデータをクラウドに保管することは信頼構築の問題であることに同意しましたが、それを実現する方法については意見が分かれました。

Jun 28, 2015 · 2 min read