Objective-C でも、Ruby みたいに動的にメソッドを追加することができた。 ということは、Objective-C でもメタプログラミングができるね。
今のところ、セレクタを引数に受け取るメソッドのテストで重宝している。
#import "MyTests.h" #import <objc/runtime.h> @implementation MyTests - (void)testAddDynamicMethod { __block BOOL called = NO; // メソッドの本体になるブロック // 第1引数は self を受け取る void (^testBlock)(id, NSNotification*) = ^(id self, NSNotification *notificateion) { called = YES; }; // セレクタを作成 SEL sel = NSSelectorFromString(@"testMethod"); // ブロックからメソッドの実装を作成 IMP imp = imp_implementationWithBlock(testBlock); // クラスのメソッドに追加 class_addMethod([MyViewControllerTests class], sel, imp, "v@:@"); // @selector には NSSelectorFromString に指定した名前を渡す [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(testMethod) name:@"foo" object:nil]; NSNotification *n = [NSNotification notificateionWithName:@"foo" object:self]; [[NSNotificationCenter defaultCenter] postNotofication:n]; STAssertTrue(called, @"ブロックは呼ばれました"); }
class_addMethod の最後の引数で渡している文字列は、メソッドのシグネチャ文字列。