Objective-C 中是否有类似 Ruby 的 send 方法的“等价物”?

4

我不确定这是否可能,但在Ruby中,你可以使用send动态调用方法。

例如,如果我想要为对象foo调用bar方法,我可以使用:

foo.send("bar")

有没有使用Objective-C实现类似功能的方法?
谢谢!
3个回答

13
据我所知,有以下几种选项:
  1. 您可以使用NSObject的 performSelector: 方法。然而,这种方法只适用于没有或只有少数参数的方法。
  2. 使用 NSInvocation 类。这种方法比较笨重,但更加灵活。
  3. 您可能能够使用 objc_msgSend(),但直接调用它可能不是一个好主意,因为运行时可能在幕后做了其他处理。

对的,只有 performSelector:performSelector:withObject:performSelector:withObject:withObject: 这几个方法可以使用——超过两个参数就不再是可行的选择了。我记得 NextSTEP 曾经有一个 performv: 方法,允许使用可变参数之类的东西,但我不太确定…… - ephemient
超过两个参数时,您可以使用NSInvocation或切换到使用字典作为参数。这并不难,只需要多调用几个方法即可。 - Kendall Helmstetter Gelner
此外,仅当参数类型全部为对象且返回类型为对象或void时,1.才是有效的。 - user102008

3

对于一般用途(具有返回值和任意数量参数的方法),请使用NSInvocation

if ([target respondsToSelector:theSelector]) {
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
        [target methodSignatureForSelector:theSelector]];
    [invocation setTarget:target];
    [invocation setSelector:theSelector];
    // Note: Indexes 0 and 1 correspond to the implicit arguments self and _cmd, 
    // which are set using setTarget and setSelector.
    [invocation setArgument:arg1 atIndex:2]; 
    [invocation setArgument:arg2 atIndex:3];
    [invocation setArgument:arg3 atIndex:4];
    // ...and so on
    [invocation invoke];
    [invocation getReturnValue:&retVal]; // Create a local variable to contain the return value.
}

-1
if ([foo respondsToSelector:@selector(bar)])
    [foo performSelector:@selector(bar))];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接