exchange NSObject#autorelease
昨日までの実験だが、結局のところ NSAutoreleasePool#addObject:
を置き換えるのが目的ではない。もともとはコンビニエンスコンストラクタが、オブジェクトを自動解放プールに登録するのかどうかを確認したかったのである。であれば NSAutoreleasePool
のサブクラスを作って、それをトップの自動解放プールとするだけで確認できた。
しかし Cocoa Application の中では自動的に自動解放プールが作られるのでそれは無理である。
ということは NSAutoreleasePool#addObject:
がだめなら NSObject#autorelease
をフックしてみてはどうか。
@interface NSObject (TESTAutoreleasePool) -(id)TEST_autorelease; @end @implementation NSObject (TESTAutoreleasePool) +(void)load { if (self != [NSObject class]) return; Method originalMethod = class_getInstanceMethod(self, @selector(autorelease)); Method replaceMethod = class_getInstanceMethod(self, @selector(TEST_autorelease)); method_exchangeImplementations(originalMethod, replaceMethod); NSLog(@"method %s was exchanged with %s\n", method_getName(originalMethod), method_getName(replaceMethod)); } -(id)TEST_autorelease { NSLog(@"exchanged method was called\n"); NSLog(@"method = %s#%s\n", object_getClassName(self), sel_getName(_cmd)); return [self TEST_autorelease]; } @end int main (int argc, const char * argv[]) { NSAutoreleasePool *pool; id anObject; // --> method autorelease was exchanged with TEST_autorelease pool = [[NSAutoreleasePool alloc] init]; [NSString stringWithUTF8String:"<autorelease>"]; // --> exchanged method was called // method = NSCFString#autorelease [[[NSObject alloc] init] autorelease]; // --> exchanged method was called // method = NSObject#autorelease anObject = [[NSObject alloc] init]; [pool addObject:anObject]; // 何も出力されない [pool drain]; return 0; }
期待通り autorelease
をフックできたようだ。