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:]の返り値として不適切なものが存在する。
それら不適切なものを扱う場合の対処法について。
…