NSInvocationの作成


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で受け取ります。

NSInvocationの作成」への1件のフィードバック

  1. boreal-kiss.com

    -[NSObject performSelector:]の返り値

    まとめ
    -[NSObject performSelector:]の返り値として不適切なものが存在する。
    それら不適切なものを扱う場合の対処法について。

    返信

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です