Hatena::Groupiphone-dev

iPhoneアプリ開発まっしぐら★ このページをアンテナに追加 RSSフィード

引っ越し後の日記はコチラです

tokoromのその他の日記

2009-07-15

メソッドの動的な呼び出し(2)

08:10 | はてなブックマーク - メソッドの動的な呼び出し(2) - iPhoneアプリ開発まっしぐら★

前のエントリの続きです。

引数が2つの場合には、performSelector:withObject:withObject:メソッドを使えばよかった。

それでは、引数が3つ以上の場合にはどうするか?

少し複雑だが、NSInvocationを使った動的なメソッド呼び出しを行う必要がある。以下に具体的なサンプルコードを示す。

  SEL selHaving3args = NSSelectorFromString( @"methodHaving3args:arg2:arg3:" );
  if ( [self respondsToSelector:selHaving3args] ) {

    NSMethodSignature* sig = [self methodSignatureForSelector:selHaving3args];
    // NSInvocationをNSMethodSignatureから作成
    NSInvocation* inv = [NSInvocation invocationWithMethodSignature:sig];
    // NSInvocationにセレクタを設定
    [inv setSelector:selHaving3args];
    // NSInvocationに戻り値を設定
    BOOL ret = YES;
    [inv setReturnValue:&ret];
    // NSInvocationに引数を設定(indexの0と1は予約済みのため2から指定)
    NSString* arg1 = @"ARG1";
    NSString* arg2 = @"ARG2";
    NSString* arg3 = @"ARG3";
    [inv setArgument:&arg1 atIndex:2];
    [inv setArgument:&arg2 atIndex:3];
    [inv setArgument:&arg3 atIndex:4];

    // メソッドの実行
    [inv invokeWithTarget:self];
  }

ここでは、戻り値と3つの引数を持つmethodHaving3args:arg2:arg3:メソッドの動的な呼び出しを行っている。

まず、NSInvocationクラスのオブジェクトを作成するためには、invocationWithMethodSignature:メソッドを使い、その引数にNSMethodSignatureクラスのオブジェクトを渡す必要がある。NSMethodSignatureクラスのオブジェクトは、methodSignatureForSelector:メソッドの引数セレクタを渡すことで作成できる。

NSInvocationクラスのオブジェクトが作成できたら、setSelector:メソッドでセレクタ、setReturnValue:メソッドで戻り値、setArgument:atIndex:メソッドで引数をそれぞれ設定する。

戻り値引数は、その実体ではなくアドレスを渡す必要がある。

また、ここが一番分かりにくいのだが、setArgument:atIndex:に渡すインデックスは2以降でなければならない。0と1は暗黙の引数として予約されているインデックスだからだ。第1引数なら2、第2引数なら3と指定する。

NSInvocationクラスのオブジェクトが完成したら、invokeWithTarget:を使ってメソッドを実行することができる。

------

ちなみに前のエントリで名無しさんからThree20をご紹介いただいた。

Three20はかなり出来のいい便利なライブラリだ。Three20では、NSInvocationを使ってperformSelector:withObject:withObject:withObject:というメソッドをNSObjectに追加している。