Introduction

備忘録。
ARC (Automatic Reference Counting) 、要するに自動参照カウントだがこの機能が有効だと、クラスインスタンスが不要になった時、クラスインスタンスによって使用されていたメモリを自動的に解放する。
メモリ管理の自動化だが、GC とは異なる

  • ARC
    • コンパイル時に参照を自動カウントして開放コードを挿入するため実行時のオーバーヘッドが少ないが、参照カウントの増減の操作はオーバーヘッドとなる
    • Objective-C と Swift で採用
  • GC
    • 実行時に定期的にメモリを掃除するため、そのプロセスが実行される間、アプリケーションの動作が一時停止する可能性がある
    • Java、.NET言語、Go、Ruby、Python 等で採用

そんな ARC、使い方を誤るとクラッシュする。

What is happened?

きちんと ARC の挙動をしっかり理解する必要がある。

メソッドの接頭辞 ARC 有効時 ARC 無効時 (MRC)
alloc, new 明示的な操作は不要 retain 不要、release 必要
copy, mutableCopy 明示的な操作は不要 retain 不要、release 必要
それ以外 明示的な操作は不要 autorelease または retain, release による管理が必要
  • ARC 環境
    • 明示的に retain, release, autorelease を使用することは禁止で、コンパイルエラーになる。
  • MRC (Manual Reference Counting) 環境、つまりARCが無効な環境
    • alloc, new, copy, mutableCopy の接頭辞で始まるメソッドから取得したオブジェクトは手動でリリース(release)する必要がある
    • 上記の接頭辞以外のメソッドから取得したオブジェクトは、そのメソッドの実装やドキュメントに応じて、適切にメモリ管理を行う必要がある。多くの場合 、返されるオブジェクトは autorelease 済みとなっているが、明確でない場合はドキュメントやメソッドの実装を参照する必要がある。

そのため、ARC 無効の環境において下記のようなコードで

1
2
3
4
5
NSString *objcString = [NSString stringWithUTF8String:number];

// something to do

[objcString release];

のように release するとクラッシュする可能性がある (事実クラッシュする)。

ARC 有効ならそもそもビルド時に下記のようなエラーが出るので心配はない。

1
2
/Users/xxxxxx/Demo/src/sample.mm:18:17: error: 'release' is unavailable: not available in automatic reference counting mode
[objcString release];

オブジェクトが自動解放されるかはドキュメントや実装を確認するとあるが、上記のメソッド stringWithUTF8String のドキュメントを見ても、自動解放されるかがわからない。
Apple の実装だから、特定の接頭辞がついてなければ無条件で自動解放と考えればいいのか、と思うが…