2009年8月3日月曜日

autoreleaseされたオブジェクトが解放されるタイミング

autoreleaseを使いすぎるとNSAutoreleasePoolに解放待ちのオブジェクトがたまってメモリを圧迫してしまう。と、思っていてinit/releaseを使うようにしていたのだけど、Application KitやUIKitの場合はそうではないようだ。

クラスリファレンスによると、メインスレッドでイベントループの最初にNSAutoreleasePoolが作られ、イベントループの最後にreleaseが送られるということらしい。つまり、イベントループが一周するごとにautoreleaseされたオブジェクトは解放されることになる。XCodeのテンプレートでは、main()の最初にNSAutoreleasePoolを作り最後にreleaseしていたので、autoreleaseされたオブジェクトはプログラムの終了時まで解放されないと勘違いしていた。

ということで、作ったオブジェクトをautoreleaseしたり、autoreleaseされたオブジェクトを返すメソッドを呼んだりしても、メモリについてはそんなに気にしなくていい。ただし、ループなどでautoreleaseされたテンポラリオブジェクトが大量に作られる場合は、自分でNSAutoreleasePoolを用意し解放するようにしたほうがいい。

while (/* ... */) {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    
    /* autoreleaseされたテンポラリオブジェクトを大量に作る */
    
    [pool release]
}

参考