この記事は旧ブログ(amuns:blog)の記事です。

iPhoneの開発で気をつけなければならない点のひとつに、メモリリークがあります。
普段JavaやPHPでプログラムを組んでいる人であればあまり馴染みが無いかもしれませんが、きちんとコーディングしなければリークが発生します。

Javaはガベージコレクションがあり、勝手に解放をしてくれますが、iPhone開発ではちゃんとした対処が必要です。
iPhoneの開発ではガベージコレクションは使えません。
限られたリソースしか無いため、自分自身でメモリの管理が必要です。

メモリリークの対処をしないと、非常にアプリが不安定になります。

基本的にはallocした変数はreleaseが必要です。
Objective-cの開放やメモリ管理は、ここでは説明しませんが色々と知識がないと難しいです。
参考書等を必読しましょう。

今回はもしアプリを一通り作成したとして、便利なツールを紹介しましょう。
ソース量が多くなれば、一つ一つ開放したか確認するのは大変ですが、Xcodeの解析ツールを使ってみましょう。

ここではビルドタイプをDeviceに切り替えます。
以下のソースのように、あえて開放をコメントアウトしましょう。

-(void) buttonClick {
  // アラートテスト
  UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"タイトル"
      message:@"テストボタンがクリックされました"
      delegate:nil
      cancelButtonTitle:@"OK"
      otherButtonTitles: nil];
  [alert show];
  // あえてコメント
  //[alert release];
}

次にXcodeのBuild and Analyzeを実行します。

mac_iphone9

すると以下のように、マークが付きます。

mac_iphone10

青いマークをクリックするとさらに、詳細?にラインがでてきます。

mac_iphone11

object leakedと出ていますね。
それ以外にも、以下のようにロジック的に開放忘れが発生しそうな場合も同様に解析で分かります。
今回はちゃんとリリースしていますが、条件分岐でメソッドの処理を終了します。
こういう書き方はもちろん無いですが、メソッドの先頭でallocして、メソッドの終わりでreleaseしている場合、途中の入力チェックなどでreturnする場合とか注意です。

-(void) buttonClick {
  // アラートテスト
  UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"タイトル"
      message:@"テストボタンがクリックされました"
      delegate:nil
      cancelButtonTitle:@"OK"
      otherButtonTitles: nil];
  [alert show];

  if (YES) {
    // 例外処理など
    return;
  }

  [alert release];
}

解析すると以下のように知らせてくれます。

mac_iphone12

非常に便利ですね。
ただしこのツールで完璧にリークを取り除けません。
allocとreleaseのワンセットは基本ですが、それ以外でもリークしてしまう場合があります(retainなど)

さらにリークを探すツールLeaksというものがあります。
次の記事で説明します。