NSAutoreleasePool祭り

なぜかTLがNSAutoreleaseであふれてたので以前から気になってた事を試したよ!

どこかのひと曰く

例外処理の@finallyブロック内でNSAutoreleasePoolを解放する必要はないよ!

にわかには信じられませんでしたが、試す気もありませんでした。

今回これを検証してみましょう!

@interface Hoge : NSObject
@end

@implementation Hoge
- (id)init
{
	[super init];
	NSLog(@"Initialized -> %p", self);
	return self;
}
- (void)dealloc
{
	NSLog(@"Deallocate -> %p", self);
	[super dealloc];
}
@end

@implementation TestAutoreleasePoolAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
	id pool01 = [[NSAutoreleasePool alloc] init];
	@try {
		id pool02 = [[NSAutoreleasePool alloc] init];
		Hoge *hoge = [[[Hoge alloc] init] autorelease]; // pool02 にプールされるよ!
		
		[[NSArray array] objectAtIndex:0];	// raise Range Exception!
		
		[pool02 release]; // ここには到達しないよ!
	}
	@catch (id ex) {
		// 何もしないよ!
	}
	NSLog(@"Before pool01 release");
	[pool01 release];
	NSLog(@"After pool01 released");
}
@end

いつもながらの適当すぎるネーミングです!
やってる事は

  1. NSAutoreleasePoolを2つ確保する。
  2. 一番内側でHogeオブジェクトをautorelease
  3. @tryブロック内で例外を発生させる
  4. HogeオブジェクトをプールさせたNSAutoreleasePoolは解放されない
  5. 外側のNSAutoreleasePoolは解放させる

結果

2011-01-14 00:35:49.165 TestAutoreleasePool[18685:a0f] Initialized -> 0x10014d1d0
2011-01-14 00:35:49.168 TestAutoreleasePool[18685:a0f] Before pool01 release
2011-01-14 00:35:49.168 TestAutoreleasePool[18685:a0f] Deallocate -> 0x10014d1d0
2011-01-14 00:35:49.169 TestAutoreleasePool[18685:a0f] After pool01 released

外側のNSAutoreleasePoolが解放されるタイミングでHogeオブジェクトが解放されました。

てことで、
例外処理の@finallyブロック内でNSAutoreleasePoolを解放する必要は(たぶん)ないよ!