-performSelector
方法的返回类型为id
,我在Apple文档中发现了这一点:
For methods that return anything other than an object, use NSInvocation.
但以下代码效果很好:
BOOL boolValue = (BOOL)[self performSelector:@selector(boolValue)];
它可以返回id
,BOOL
,NSInteger
等。我想知道该怎么做?因为投了BOOL
或者在return语句中NSInteger
到id
导致错误:
Cast of 'NSInteger' (aka 'long') to 'id' is disallowed with ARC
提前致谢!
----编辑----
感谢您的回答。
我知道这样做并不好,我也知道如何使用NSInvocation,我只是想知道-performSelector
方法是如何实现的。
答案 0 :(得分:4)
除了在其他答案中使用NSInvocation
之外,如果您在编译时知道类型,也可以直接调用实现函数。
SEL sel = @selector(boolValue);
IMP imp = [self methodForSelector:sel];
BOOL value = ((BOOL (*)(id, SEL))imp)(self, sel);
你必须将imp
转换为正确的类型,否则它是未定义的行为并且如果你幸运的话会崩溃。
答案 1 :(得分:2)
获取返回值的最佳方法是使用NSInvocation而不是执行选择器。以下是example: -
SEL selector = NSSelectorFromString(@"someSelector");
if ([someInstance respondsToSelector:selector]) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
[[someInstance class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:someInstance];
[invocation invoke];
float returnValue;
[invocation getReturnValue:&returnValue];
NSLog(@"Returned %f", returnValue);
}
答案 2 :(得分:1)
首先,您的代码不起作用:要查看它是如何被破坏的,请在64位系统上运行它。在32位系统上,它通过一次不幸的事故but on 64-bit systems the upper half of the returned value will contain garbage data运行。这是因为BOOL
会在将结果返回给您之前强制转换为id
,这会导致未定义的行为。
要做得对,请查看Stack Overflow上的众多答案之一 - 例如,this one。
答案 3 :(得分:0)
您编写的代码仅适用于您滥用类型。选择器boolValue返回的BOOL被强制转换为id,然后返回BOOL。这是有风险的,因为id字段的长度不能保证与BOOL的长度相同。
ARC对id返回类型进行了额外的处理,因此这种滥用行为根本不起作用,这就是你得到编译错误的原因。有一个桥接黑客可以使它工作,但我在这里重复它,因为它完全没有必要,将导致真正糟糕的代码。
有关正确执行此操作的详细信息,请参阅此问题:iPhone: performSelector with BOOL parameter?