在Objective-C中使用两个以上的参数执行动态类方法调用

时间:2013-07-29 12:18:23

标签: ios objective-c cocoa

我有一个方法可以动态创建不同类的新对象,并希望能够在创建这些类时对这些类执行选择。使用performSelector: withObject:会有效,但方法有四个参数。我使用NSInvocation尝试了以下代码,但是因为它是一个无法识别的选择器而出现了错误。

NSInvocation *call = [NSInvocation invocationWithMethodSignature:[NSClassFromString(className) methodSignatureForSelector:@selector(packWithName:value:writer:forClass:)]];
[call setArgument:&arg1 atIndex:0];
[call setArgument:&arg2 atIndex:1];
[call setArgument:&arg3 atIndex:2];
[call setArgument:&arg4 atIndex:3];
call.target = NSClassFromString(className);
[call invoke];

它还会生成以下日志语句:

*** NSForwarding: warning: selector (0x8ed78d0) for message '[garbled random characters]'
does not match selector known to Objective C runtime (0x8b0cd30)-- abort

我还尝试使用alloc / init创建NSInvocation并设置@selector,如下所示:

NSInvocation *call = [[NSInvocation alloc] init];
call.selector = @selector(nameofselector);

然而,这导致call为零,所以我猜这是不允许的。

我是否遗漏了有关NSInvocation如何运作的信息,或者是否有更明智的方法可以做到这一点?

2 个答案:

答案 0 :(得分:5)

索引0和1处的参数方法调用的前两个显式参数,但是隐式self_cmd参数。请改用指数2,3,4和5.

答案 1 :(得分:3)

Apple文档只是说明第一个参数(带有indice 0)代表目标对象(所以“自我”)。正如文档所解释的那样,第一个参数是使用setTarget:方法设置的。

所以你需要从2开始使用NSInvocation的索引。(这意味着你的代码应该是这样的)

NSInvocation *call = [NSInvocation invocationWithMethodSignature:[NSClassFromString(className) methodSignatureForSelector:@selector(packWithName:value:writer:forClass:)]];
[call setArgument:&arg1 atIndex:2];
[call setArgument:&arg2 atIndex:3];
[call setArgument:&arg3 atIndex:4];
[call setArgument:&arg4 atIndex:5];
call.target = NSClassFromString(className);
[call invoke];