可以使用NSSelectorFromString传递参数(即BOOL)吗?

时间:2014-12-11 04:52:30

标签: objective-c arguments selector

而不是像这样的代码:

switch(levelNumber) {
   case 1: [Settings unlockLvl1:YES]; break;
   case 2: [Settings unlockLvl2:YES]; break;
   case 3: [Settings unlockLvl3:YES]; break;
   case 4: [Settings unlockLvl4:YES]; break;
...
}

我希望像这样使用NSSelectorFromString:

NSString *selectorString = [NSString stringWithFormat:@"unlockLvl%i", levelNumber];
SEL s = NSSelectorFromString(selectorString);
[Settings performSelector:s];

但是,当我以这种方式调用选择器时,我不确定是否可以正确插入(BOOL)YES参数?我还希望能够将int参数传递给使用选择器调用的方法(如果可能的话)。

将其添加到选择器字符串会导致“无法识别的选择器”异常并崩溃。

[Settings performSelector:s withObject:???];可以工作?但是不接受BOOL或int,需要“id”

我正在尝试编写我的代码,以便每个级别没有多个代码块,但功能完全相同但只是更改了一个数字。

任何帮助将不胜感激! 如果不可能......也许还有另一种更好的方式?

2 个答案:

答案 0 :(得分:3)

有两种方法可以做到这一点。

这部分对两者都很常见:

NSString *selectorString = [NSString stringWithFormat:@"unlockLvl%i:", levelNumber];
SEL selector = NSSelectorFromString(selectorString);

1)使用NSInvocation

BOOL boolArg = YES;

NSMethodSignature* signature = [NSMethodSignature signatureWithObjCTypes:"v@:B"];
// or:
// NSMethodSignature* signature = [Settings.class methodSignatureForSelector:selector];
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.target = Settings.class; // or class instance
invocation.selector = selector;
[invocation setArgument:&boolArg atIndex:2];
[invocation invoke];

2)使用原始方法:

typedef void (*MethodWithBoolArg)(id, SEL, BOOL);

MethodWithBoolArg method = (MethodWithBoolArg)[Settings.class methodForSelector:selector];
if (method != NULL)
    method(self, selector, YES);

答案 1 :(得分:1)

您可以使用performSelector:withObject:,但需要将BOOL打包在NSNumber中。然后你的方法需要打开NSNumber

BOOL someBool = YES; // or NO
[Settings performSelector:s withObject:@(someBOOL)];

您的每个unlockLvlX方法都需要使用NSNumber参数:

- (void)unlockLvl1:(NSNumber *)theBool {
    BOOL boolVal = [theBool boolValue];
    // do stuff with boolVal as needed
}