variadic method (その2)

いろいろ調べてみたが、やはり可変引数をそのままobjc_msgsendに渡すことは出来ないようなので、当初考えていたNSInvocationsとNSMethodSignatureを使って実装することにする。

NSObject+MethodUtil-invokeMethodNamed
- (id)invokeMethodNamed:(NSString*)name forParams:(id) params,... 
{
    va_list args;
    va_start(args, params);

    SEL selector = NSSelectorFromString(name);
    NSMethodSignature* sig = [self methodSignatureForSelector: selector];
    NSInvocation* inv = [NSInvocation invocationWithMethodSignature:sig];
    [inv setTarget: self];
    [inv setSelector:selector];
    
    unsigned int index = 2; 
    for (id arg = params; arg != nil; arg = va_arg(args, id))
    {
        [inv setArgument:(void*)&arg atIndex:index];
        index++;
    }
    va_end(args);

    [inv setArgument:nil atIndex:index];
    [inv invoke]; //実行

    id retVal;
    [inv getReturnValue:(void*)&retVal];
    return retVal;
}

ポイントはva_listを使うためにva_startマクロ、使用が完了したらva_endマクロを使うことだ。

これでいいはずだが、まだ問題がある。
引数、戻り値もこのままではid型しか扱えないということだ。 特にスカラ型をどうするか。