あたらしものずきっ!

試してみたものとか、遊んでみたものを色々記してみます。

iPhone SDKにおけるautoreleaseの是非

Interface Builderを捨てて完全にXcodeだけで作成するようになって、メモリ操作に気を使うケースが結構多くなってきたので、気をつけてることを書いてみることにする。

特に知識がなかったころは馬鹿正直にautoreleaseを使って放置してたんだけど、main.mに記述されているNSAutoreleasePoolの存在を知って、且つ NSAutoreleasePoolの動作を知って以来微妙だよなぁと思ってる。

autoreleaseの動作

main.mに記述されているNSAutoreleasePoolの役割をおおざっぱに書くと、ソースコード上でautoreleaseのメッセージが送られたオブジェクトの、メモリ上からの解放処理をまとめて担うという代物で、メモリ上での解放処理に細かく気を使わなくてよくなるのが特徴。ただ解放のタイミングとか指定がしにくい(できない?)から、結構メモリを食いがちになる。

使ってないのにメモリ占有とかしちゃったりするから、事細かく操作したいときにはやっぱ個別にreleaseしたいんだけど、autorelease指定している場合はreleaseが使えない。

autoreleaseの問題点

autoreleaseで問題なのは、オブジェクト生成時にalloc,init(およびinitXXXメソッド)の組み合わせにて生成していない等の、意識せずに使ってしまっている時。

例えば

NSArray *array = [NSArray array];

みたいな具合。このケースではオブジェクト生成時に内部で自動的にautoreleaseがかかってしまうものだから、リリースのタイミングを細かく指定できないため無駄に抱えてしまう、ということになりうる。

なぜか異様に処理が重いアプリなんかは全部autoreleaseに任せっきりなケースなんて可能性もあり。ちなみに、一度全部autorelease任せにしたら処理のトロさが使い物にならないレベルに発展してやばくなったこともある。

代替案

代替案といっても、生成には一貫してalloc, initを用いて、viewに加えた場合なかは後で忘れずにreleaseを使う、とかそんな感じ。NSStringとかstringWithFormatでいきなり済ませるタイプの人もいるんだろうけど、これも

NSString *str = [[NSString alloc] initWithFormat:@"hoge%@", @"hoge"];

な具合でひと手間かけると、releaseを忘れなければ幸せになれる気もしてる。

autorelease推奨って具合に書いてる人も多いけど、それなりに処理を覚えてきたら手抜きせずに行きましょうということで。

その点からみると、多分インフォシティのBB2Cはメモリ管理が超優秀なんだろうな。