【问题标题】:How can I perform an obj-c message with a selector and variable number parameters? [duplicate]如何使用选择器和可变编号参数执行 obj-c 消息? [复制]
【发布时间】:2014-03-04 04:02:41
【问题描述】:

有没有这样的方法:

- (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 运行时实现这一点?不可能吗?

【问题讨论】:

  • @MichaelDautermann no answer in that question提供了一种将数组作为参数的方法。
  • 嗯,@BryanChen;我在重复问题中的回答具体展示了如何在参数中使用数组。
  • @MichaelDautermann 好吧,你或我都误解了这个问题。我认为 OP 正在寻求一种方法来调用 someMethod:withArg:andArg:andArg:,并将参数打包在一个数组中。不将数组传递给someMethodTakesArray:
  • 我同意 Bryan 的观点;迈克尔的回答并没有完全符合要求,but valvoline's does

标签: objective-c


【解决方案1】:

使用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 或 return double 的东西。

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

阅读this question获取更详细的答案

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-20
    • 2015-06-12
    相关资源
    最近更新 更多