NSAutoreleasePoolのメモ

オブジェクトに対してautoreleaseを送信すると、NSAutoreleasePoolというautoreleaseを管理するプールに入ります。で、NSAutoreleasePoolのインスタンス自身が破棄される時に、プールに入っていたものも解放されます。

    for (int idx = 0; idx < 10; idx++) {
        NSString *str = [NSString stringWithFormat:@"HOGE"];
    }
    [NSAutoreleasePool showPools];

stringWithFormatで作ったオブジェクトがプールに登録されているのがわかります。

--------------- Autorelease Pools ---------------
==== top of stack ================
  0x5901660 (NSCFString)
  0x59312b0 (NSCFString)
  0x5903540 (NSCFString)
  0x59326c0 (NSCFString)
  0x59356b0 (NSCFString)
  0x59320e0 (NSCFString)
  0x5934030 (NSCFString)
  0x5932750 (NSCFString)
  0x5930ec0 (NSCFString)
  0x59326f0 (NSCFString)
  0x4d04830 (__NSArrayI)
  ...
  0x4d57320 (__NSArrayM)
==== top of pool, 41 objects ================

NSAutoreleasePoolはスタック上に積み重なっていて、autoreleaseしたものはスタックの一番上のプールに入ります。なお、自動で作成される、一番上にあるプールはなんらかのイベント毎に解放されるとのことです。なので、例えばforループの中でautoreleaseされるオブジェクトを生成すると、一回のイベントが終わるまでに沢山のオブジェクトが解放されないままになってしまいます。

その場合、forループの中でNSAutoreleasePoolのインスタンスを自作することで、スタックの一番上に持ってきてあげれば解放されるようになります。

    for (int idx = 0; idx < 10; idx++) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        NSString *str = [NSString stringWithFormat:@"HOGE"];
        [NSAutoreleasePool showPools];
        [pool release];
    }
    [NSAutoreleasePool showPools];

自作したプールに、stringWithFormatで作成したオブジェクトが登録されています。

--------------- Autorelease Pools ---------------
==== top of stack ================
  0x5926a00 (NSCFString)
==== top of pool, 1 object ================

イベント毎に破棄されるプールには、stringWithFormatで作成したオブジェクトは登録されていません。

--------------- Autorelease Pools ---------------
==== top of stack ================
  0x5912a60 (__NSArrayI)
  ...
  0x4d49510 (__NSArrayM)
==== top of pool, 31 objects ================

この記事が役に立った場合、シェアしていただけると励みになります!!