autoreleaseのひみつ

autoreleaseで実際に何が起こるのか。 GNUstepのソースコードから調べてみたよ。
18
sakamoto.kazuki @splhack

autorelease って何が起きるの? 解答例→ http://bit.ly/guOjkV http://bit.ly/fIqS1X 根元のNSObjectのautoreleaseメソッドが、NSAutoreleasePoolのaddObjectメソッドを呼ぶだけ。

2011-01-13 16:16:39
sakamoto.kazuki @splhack

NSAutoreleasePoolのdrainかreleaseで、addObjectされてたすべてのオブジェクトにreleaseを送るだけ。

2011-01-13 16:23:23
sakamoto.kazuki @splhack

NSAutoreleasePoolがdrainかreleaseされるタイミングは? NSRunLoopが1回回るたび。自力で作ってdrainかreleaseするとき。

2011-01-13 16:52:57
sakamoto.kazuki @splhack

NSRunLoop runMode:beforeDate: の最後。このメソッドの最初でallocしたNSAutoreleasePoolをreleaseしてます。runUntilDate:でぐるぐるとrunMode:beforeDate:が呼ばれます。

2011-01-13 22:47:11
sakamoto.kazuki @splhack

GNUstepのNSRunLoopの実装はこれ http://bit.ly/f8tlCY で、今回あくまでGNUstepの実装を元にしているので、多少異なるかもしれませんが、基本的には同じはず。GCDの方はlibdispatchなのでiOSでも一緒。

2011-01-13 23:02:52
sakamoto.kazuki @splhack

ので多量のautoreleaseされるオブジェクトを使う場合、つまり、autoreleaseを呼んだり、オブジェクトを返すクラスメソッドを呼んだり(NSString string*)、する場合は自力でNSAutoreleasePool allocしてdrainすべし。

2011-01-13 16:57:18
sakamoto.kazuki @splhack

たとえば、たくさん画像を読み込む場合。ファイルを読み込んだNSDataオブジェクト。それから作ったUIImageオブジェクト。サイズを変更したりしてまたUIImageオブジェクト。てな時にautoreleaseしただけのオブジェクトが大量に残る。

2011-01-13 22:57:17
sakamoto.kazuki @splhack

for() {NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; /* 画像読み込み処理 */; [pool drain];} これでスッキリ。

2011-01-13 22:58:39
sakamoto.kazuki @splhack

releaseじゃなくてdrainを呼ぶ理由は、Mac OS XでGC活かしているときGC走るから。

2011-01-13 17:00:10
sakamoto.kazuki @splhack

Grand Central DispatchではNSAutoreleasePoolはどーなってるの? Main QueueはメインスレッドのRunLoopの話と同じ。Global Queue/Serial Queueは、threadの生成時にpool生成、終了時にpool解放。

2011-01-13 16:55:21
sakamoto.kazuki @splhack

GCD Global Queue/Serial QueueでのNSAutoreleasePoolのreleaseは、もっと細かいか。QueueにいれたBlockまたは関数ポインタ毎か。

2011-01-13 17:10:37
sakamoto.kazuki @splhack

Grand Central DispatchのGlobal/Serial Queueで動くthreadから呼ばれる http://bit.ly/eZ6ORX _dispatch_worker_thread2で、Block実行前にpool alloc、実行後pool release

2011-01-13 22:51:50
スミヒロは酒飲み🍶 @sumihiro

つーこたiOS下で回数がすげー大きいループで毎回autoreleaseしてたらdrainされる前にメモリを食いつぶすんかな。

2011-01-13 22:49:04
sakira3.1 @sakira

@sumihiro あー、それは経験しました。

2011-01-13 22:49:31
スミヒロは酒飲み🍶 @sumihiro

@sakira おー、やっぱそーゆーことなんですね。

2011-01-13 22:50:09
sakira3.1 @sakira

@sumihiro 数百回のloopの中でUIColorをautoreleaseしたらやられちゃったので、明示的にinitWith..., releaseで対応した感じです。

2011-01-13 22:53:17
スミヒロは酒飲み🍶 @sumihiro

@sakira ほほう。てことはクラスメソッドも使えない感じで?もしそうであれば面倒な話ですなぁ。

2011-01-13 22:54:37
sakira3.1 @sakira

@sumihiro なかったですね〜。というか計算式わかっているので、本来ならUIColorなんか使わないで自分で書くとこですが、本の解説用のコードだったので。

2011-01-13 22:56:21
スミヒロは酒飲み🍶 @sumihiro

@sakira UIColor自体はメモリ消費量は少なそうですが、注意が必要なんですな。どもどもー。

2011-01-13 22:58:06
スミヒロは酒飲み🍶 @sumihiro

やっぱり大量のメモリ消費が見込まれる場合はautoreleaseに頼るな、と。少なからず自分の体感が合ってて安心した。

2011-01-13 23:00:02
sakamoto.kazuki @splhack

え、クラスメソッドしかないよ! て時は、alloc,init,releaseをあきらめて、NSAutoreleasePool作りましょう。

2011-01-13 23:12:16
sakamoto.kazuki @splhack

"生成時に autorelease するのが望ましい" http://bit.ly/hsgwg7

2011-01-13 23:27:31
Hiroshi Hashiguchi @xcatsan

nonatomic無しだと参照だけで retain count が増加する件 >> Objective-Cの宣言プロパティにはまる - Basic http://bit.ly/hMsOqK

2011-01-19 06:00:20