如何使用选择器和变量编号参数执行obj-c消息?

时间:2014-03-04 04:02:41

标签: objective-c

有没有这样的方法:

- (id)performSelector:(SEL)selector withParameters:(NSArray *)parameters;

我可以调用这样的obj-c消息:

// invoke a message with 3 parameters
[obj performSelector:@selector(evaluate:name:animate:) withParameters:@[@1, @"test", @YES]];

// invoke a message with 1 parameter which is an array containing 3 components.
[NSArray performSelector:@selector(arrayWithArray:) withParameters:@[@[@1, @"test", @YES]]];

如果没有这样的方法。如何使用Obj-C运行时实现它?这不可能吗?

1 个答案:

答案 0 :(得分:2)

使用NSInvocation

- (id)performSelector:(SEL)selector withParameters:(NSArray *)parameters
{
    NSMethodSignature *signature  = [self methodSignatureForSelector:selector];
    NSInvocation      *invocation = [NSInvocation invocationWithMethodSignature:signature];

    [invocation setTarget:self];       
    [invocation setSelector:selector];            
    for (int i = 0; i < parameters.count; ++i)
    {
        id para = parameters[i];
        [invocation setArgument:&para atIndex:2+i];  
    }

    [invocation invoke];

    id ret;
    [invocation getReturnValue:&ret];
    return ret;

}

注意:此实现仅在被调用的方法将ObjC对象作为参数并返回对象时才有效。即,它不适用于int或返回double的东西。

如果您希望它适用于基本类型/结构,则必须检查NSMethodSignature的参数类型并将对象转换为该类型,然后将其传递给setArgument:atIndex:

阅读this question了解更详细的ansowers