method_setImplementation

昨日の問題。今日は class_replaceMethod ではなく method_setImplementation を使ってみた。

BOOL TEST_replaceMethod(Class replaceClass)
{
  Method replaceMethod = class_getInstanceMethod(replaceClass, @selector(addObject:));
  originalImp = method_setImplementation(replaceMethod, (IMP)TEST_addObjectImp);
  NSLog(@"replace '%s#addObject:' with 'TEST_addObjectImp'\n",
        object_getClassName(replaceClass));
  return originalImp != NULL;
}

...
  TEST_replaceMethod([NSAutoreleasePool class]);
    // --> replace 'NSAutoreleasePool#addObject:' with 'TEST_addObjectImp'
  pool = [[NSAutoreleasePool alloc] init];
  [NSString stringWithUTF8String:"<autorelease>"];  // 何も出力されない
  [[[NSObject alloc] init] autorelease];            // 何も出力されない
  anObject = [[NSObject alloc] init];
  [pool addObject:anObject];
    // --> replaced imp was called
    //     NSAutoreleasePool#addObject:
    //     arg = class NSObject(<NSObject: 0x1065c0>)
...

しかし結果は同じ。
もしかしてインスタンスメソッドではなく、クラスメソッドが呼び出されているのではないかと思い、class_getInstanceMethod ではなく class_getClassMethod を使ってみたりもしたが、結果は変わらなかった。