iOS / Macアプリを作る上で、ARCは生産性の劇的な向上が望める画期的な機能の一つです。しかし、仕事の現場では様々な理由から未だにARCを使えないケースが多くあります。
ARCとは
ARC(Automatic Reference Counting)は2011年のWWDCで発表された、Objective-Cの新しい機能の一つです。従来、Objective-Cではリファレンスカウンターという仕組みを使ってオブジェクトのRetain / Releaseをプログラマが手動で管理する必要がありましたが、ARCを使う場合基本的にRetain / Releaseを明示的に行う必要がありません。(というよりやってはいけません)
ARCのメリット
メモリ管理のためのコードが大幅に減り、プログラムの機能面の実装に集中できるようになります。また、コードが短くなり見通しがよくなり可読性も上がります。
似たような機構にGarbage Collectionがありますが、GCでは実行時のパフォーマンスロスが一定量あるのに対して、ARCでは実行時のパフォーマンスロスが極めて小さいという特徴があります。
ARCと非ARCコードの混在
ARCを使うかどうかは、プロジェクトの設定で決定します。ARCがない時代に作られたプロジェクトに関しては、XcodeにARC対応へ自動移行をしてくれる機能が用意されています。(ただしコードの内容によっては自動で移行できないときもあります)
モジュール単位での設定
特定のモジュールのみARCを無効にしたい(あるいは有効にしたい)場合はCompiler Flagsを指定します。
残念ながら後述する理由から、ミドルウェア・ライブラリ等では未だに非ARCで書かれたコードが多数あります。
- 既存のプロジェクトが非ARCで書かれているが、そこにARCで書かれたライブラリを組み込みたい
- 逆にARC対応のプロジェクトに非ARCのライブラリを組み込みたい
という場合はこの方法を使うことができます。
ただし、モジュールの数が数十数百あるような一定規模のプロジェクトでは、設定が著しく面倒くさくなります。(ターゲット単位での設定になるため、テスト用等ターゲットが複数ある場合は特に設定が面倒くさい)
静的ライブラリ・フレームワーク
ARC対応プロジェクトには、非ARCで書かれた静的ライブラリ・フレームワークをリンクできます。逆もできます。
ライブラリ・フレームワークのリンクでは、ビルド設定を個別に行う必要がないため、設定自体は楽になります。ただし、ビルドターゲットがわかれることによる、デバッグの効率の問題や、カテゴリ拡張を有効にするための設定等は若干面倒になります。
ではなぜARCを使えないのか
上述のように、ARCは非ARCコード(特にレガシーコード)との混在が少し面倒くさいという問題もあるのですが、なかなか仕事の現場で使えない事情はOSの対応にあります。
Rank | Name | iOS 4.3対応 |
---|---|---|
1 | Where’s my Mickey? | × |
2 | WhatsApp Messenger | ○ |
3 | Heads Up! | × |
4 | Minecraft – Pocket Edition | ○ |
5 | Contra: Evolution | ○ |
6 | iTranslate Voice | × |
7 | LEGO Batman: DC Super Heroes | × |
8 | AfterLight | × |
9 | Pimp Your Screen | ○ |
10 | LIMBO Game | × |
こちらは2013年7月8日時点の米AppStoreにおける有料アプリTop10です。iOS 5が発表されてそろそろ2年になりますが、未だに半数近くのアプリはiOS 4.3をサポートしています。iPhoneの93%以上は既にiOS 6というデータもあるのですが、未だに少しでもユーザの母数を増やすためにiOS 4.3をサポートするというプロジェクトは少なくありません。
そして、多くのアプリがiOS 4.3をサポートする状況では、必然的にライブラリやフレームワークもiOS 4.3をサポートするという選択肢を取らざるを得なくなります。
実はiOS 4.3でもARC Liteが使える
ARCはiOS 4.3では使えないのですが、ARC LiteはiOS 4.3でも使えます。ただし、ARC Liteではweakプロパティが使えません。
既に解放されたオブジェクトにアクセスしようとして発生するEXC_BAD_ACCESSを回避できるweakプロパティはARCの目玉の一つとして紹介されました。iOS 4.3では、そのweakプロパティが使えないことで当時は「実質的に使えない」という印象を持っていたデベロッパが多かったように思います。(自分もそう思っていました)
weakは本当に必要か?
セキュアなプログラムを書いていく上では、weakプロパティは意外と使える場面が限られてくることに気がつきます。
解放済みのオブジェクトのプロパティにアクセスしてしまっても落ちない、というのがweakプロパティの特徴ですが、逆に言うと落ちないだけで、問題の本質が解決されるわけではありません。むしろ、nilにメッセージを送る形になるので、特にログにエラーもでず、アプリも落ちないけど想定した挙動をしていない、というデバッグが面倒な状況を生み出す要因にもなり得ます。
weakがなくてもARC Liteの価値はある
もちろん、nilかどうかのチェックをいれるだけでプロパティの中身が解放済みかどうかチェックできる、というメリットがあるのは事実ですし、weakプロパティが無駄だ、使えないと言っているわけではありません。
重要なのはweakプロパティが使えなくても、ARCにはコーディング量が減って生産性・保守性が上がるというメリットがあり、iOS 4.3にも対応させることができるということです。
結論: 積極的にARCを使おう
weakプロパティを使わなければiOS 4.3でもARCの恩恵を受けられます。iOS 7のリリースも今秋に迫っている今、非ARCコードを書き続けることはレガシーコードをかき生産性を下げるだけでなく、ライブラリやフレームワークのARC移行をも拒む、業界全体の負の連鎖を担うようなものです。さあ、ARCを使いましょう。