読者です 読者をやめる 読者になる 読者になる

キノコの自省録

テクノロジーとコンテンツの融合を目指して

autoreleaseは結構怖かった

iOSのautoreleaseって何の気なしに使っていたのですが、
これって下手するとメモリリーク状態になるんですね。
メモリ管理プログラミングガイドだけはちゃんと読んでおくべきでした。


autorelease付きのオブジェクトは、NSAutoreleasePoolという自動解放プールにスタックされていきます。
自分でNSAutoreleasePoolを作らなければ、
main関数で最初に用意されるNSAutoReleasePool1つだけで、
自動解放プールのスタックを管理することになります。
そして、この自動解放プールが実際にスタックに溜まったオブジェクトを破棄するタイミングは、
NSAutoreleasePoolが破棄されるときです。
つまり、NSAutoreleasePoolがmain関数で用意される1個だけだと、
main関数抜けるまで、autoreleaseで解放することにした一時オブジェクトは解放されないわけです。
いやもう大体のiOS開発者はご存知かと思いますが。


面倒くさいからautorelease使わないようにしよう、としたとしても、
確か[NSString stringWithFormat:]や、[UIImage imageNamed:]などでは、
autorelease付きでオブジェクトが戻ってきたはずです。
第一、普通に[ [hoge alloc] init]した場合でも、hogeのinit実装によっては、
autorelease付きオブジェクトが生成される可能性があります。
ということで、WebAPIなどを使って動的に画面更新を繰り返している場合、
結局autoreleaseオブジェクトが解放スタックにボンボン投げ込まれると思います。
そうしたとき、局所的に作ったNSAutoreleasePoolを、適切なタイミングで破棄するよう、
メモリ管理をしなければならないということになります。
動的更新している場合、適切なタイミングっていつだよって話になるわけで、
C++のように普通にnew/deleteをさせてくれた方が余程ありがたい気がします。