NSInvocationOperationとか使っていて、NSInvocationの作り方が良くわからなかったので、自分で作る方法を調べてみました。以下のコードがNSInvocationを使ってtest:というメソッドを呼び出してみたものです。
#import <Cocoa/Cocoa.h> @interface InvocationTest : NSObject { } @end @implementation InvocationTest - (void)awakeFromNib { SEL selector; NSMethodSignature *signature; NSInvocation *invocation; selector = @selector(test:); signature = [[self class] instanceMethodSignatureForSelector:selector]; if (signature) { invocation = [NSInvocation invocationWithMethodSignature:signature]; [invocation setSelector:selector]; [invocation setTarget:self]; NSString *sendString = @"send"; [invocation setArgument:&sendString atIndex:2]; [invocation invoke]; id returnValue; [invocation getReturnValue:&returnValue]; NSLog(@"%@", returnValue); } [NSApp terminate:self]; } - (id)test:(id)object { NSLog(@"call test with %@", object); return @"return"; } @end
まず、NSMethodSignatureというのがないとNSInvocationがインスタンス化できないので、instanceMethodSignatureForSelector:で作成します。これはNSObjectのクラスオブジェクトですが、呼び出すクラスにお目当てのメソッドが無いとNSMethodSignatureの作成に成功しません。
NSMethodSignatureのインスタンスが作成できたら、NSInvocationのクラスメソッドであるinvocationWithMethodSignature:でNSInvocationのインスタンスを作成します。
ターゲットとなるオブジェクトと、ここでもセレクタを設定します。さらに引数も渡せますが、setArgument:index:メソッドのインデックスに渡す数字は2からになります。リファレンスには0はselfで、1は_cmdがすでに使われているというような事が書いてあります。
invokeで登録したメソッドが呼び出されます。返り値がある場合はNSInvocationのインスタンスに保持されていますのでgetReturnValueで受け取ります。
-[NSObject performSelector:]の返り値
まとめ
-[NSObject performSelector:]の返り値として不適切なものが存在する。
それら不適切なものを扱う場合の対処法について。
…