是否可以在Objective-C中将方法作为参数传递?

时间:2009-02-06 08:54:59

标签: objective-c method-signature

我有一个方法因内部的单个方法调用而变化,我想传递方法/签名的方法/它作为参数变化...这在Objective C中是可能的,或者也是如此非常希望?

3 个答案:

答案 0 :(得分:25)

NSInvocation是一个用于在对象中包装方法调用的类。您可以设置选择器(方法签名),按索引设置参数。然后,您可以设置目标并调用invoke以触发调用,或者保持目标未设置并使用invokeWithTarget:在某种循环中在多个对象上调用它。

我觉得它有点像这样:

NSInvocation *inv = [[NSInvocation alloc] init];
[inv setSelector:@selector(foo:bar:)];
[inv setArgument:123 atIndex:0];
[inv setArgument:456 atIndex:1];

for (MyClass *myObj in myObjects) {
  [inv invokeWithTarget:myObj];
}

或者,如果您不想将调用对象传递给此方法,则可以使用SEL类型接受选择器(方法签名)。

-(void)fooWithMethod:(SEL)selector;

然后将选择器分配给调用对象,以便在对象上调用它。

答案 1 :(得分:10)

或者,如果您使用的是fooWithMethod:(SEL)selector方法,只需对其进行[myObject performSelector:selector],如果没有其他参数。

请参阅NSObject for details

答案 2 :(得分:3)

如前所述,您可以传递要调用的方法的选择器。使用选择器有不同的方法来实际调用该方法:

  1. 使用NSObject s performSelector:performSelector:withObject:performSelector:withObject:withObject:方法
  2. 使用NSInvocation对象
  3. 或直接使用objc_msgSendobjc_msgSend_stret
  4. 使用IMP
  5. 可以获得的methodForSelector:方法

    使用哪一个真的取决于具体情况。如果性能不重要,如果你需要传递0,1或2个对象,我会继续使用1。如果performSelector:...方法不匹配,我会选择2或3.由于设置NSInvocation对象需要很多样板代码我更喜欢3,但我想这是个人选择的问题,除非存在性能问题。

    如果这些方法调用的性能确实很重要,我会使用3或4. 3除非你可以缓存IMP,否则应该更快。但是根据你的代码,这可能不可行或者没有真正帮助。所以在这里你必须分析代码,看看哪个更适合你。