iOSのARC作法について

今さらiOSプログラミングのARCについてです。

これまで頑なに職人魂でARCなんぞ使わないで自分でretain、releaseとかしてたんです。

しかし、世の中の便利ライブラリなどがいよいよARCであることが前提となってきたので、ARC対応コードを書き始めました最近。

その時に分かった事をメモです。

主にプロパティに関する話です。

XCode5前提です。

これまで何も考えず、

@property (assign, nonatomic) int hoge1;
@property (retain, nonatomic) NSObject *hoge2;

とか、スカラー変数はassign、オブジェクトはretainとしてたんです。

ARC時代ではretainなんて記述してると古くさいみたいで、weak, strongが推奨されてるみたいです。

実際に、新しいアプリを作ると、AppDelegate.hのwindowはstrongになってますね。

まあ動作自体は同じみたいですが。

また、オブジェクトでもIBOutletなやつとかdelegateなどの参照側で解放する必要の無いものはweakにすると、ビューコントローラーがアンロードされる時にnilをわざわざ代入して、もういらねえよって教えなくても良きに計らってくれるみたいですね。

まとめると、

@property (assign, nonatomic) int hoge1;
@property (strong, nonatomic) NSObject *hoge2;
@property (weak, nonatomic) IBOutlet UIView *hoge3;

みたいな感じでしょうか。

そして、@synthesize。

@synthesizeはもうお払い箱です。記述しなくて構いません。勝手に指定した事になります。

なので、

self.hoge = @"hogehoge";

とも書けますし、

_hoge = @"hogehoge";

でもOKです。

え、そのアンダーバー何? って思われる方もいらっしゃるかもしれませんが、プロパティの実態はプロパティ名に_をつけた名前のpublicなメンバ変数です。

ていうか、そもそも、プロパティ使うのはnilを代入したら勝手に解放してくれて楽だから使ってましたって方も多いんじゃ無いでしょうか。

そうなんすよ、もうプロパティなんかにこだわる事もないんです。

だから、クラス内でしか使わないような変数は、全部メンバ変数にしちゃってもいいんです。

NSObject *_hoge;

とかやれば、nilで初期化されて使えます。この時、自動的に__strong修飾子がついてる事になるみたいです。

なので、メンバ変数内でdelegateを持っていたいような場合は、あえて

__weak id<HogeDelegate> _delegate;

みたいに修飾子をつけないとダメですね。

じゃあもうオブジェクトの解放なんてもう意識しなくていいって話になればいいんですが、やはりそうもいきません。

オブジェクトの解放は、誰も参照しなくなったとき、なんですよね。

なので、AというオブジェクトとBというオブジェクトがお互い参照しあっているような場合は、永久にオブジェクトが解放されません。

つまりメモリリークします。

さっき漫然とweakとかstrongとか書いてましたけど、上記の話はstrongの場合です。

じゃあweakって何かっていうと、参照していたオブジェクトが解放されたら、自分も勝手にnilになるという仕組みなのです。

たいてい、親になるオブジェクトが子になるオブジェクトをstrongで保持し、子になるオブジェクトが親になるオブジェクトを参照したければweakで保持します。

これならお互い強固に参照しあってお互い解放されないという事はありません。

なので、delegateとかはweakを指定してるんですね。

他にも色々作法というか使えない記述がありますが、例えばautoreleaseとかつけるとコンパイル時に怒られますから、ここで書くほどの事はないです。