performSelector的返回值是什么:如果我传递一个返回基本类型(在对象上)的选择器,例如NSDateComponents上的'week'(将返回一个int)?
答案 0 :(得分:79)
使用NSInvocation返回float的示例:
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);
}
答案 1 :(得分:9)
我认为你无法从performSelector获取返回值。你应该研究NSInvocation
。
答案 2 :(得分:3)
要回答问题的第二部分,另一种调用返回原语的选择器的方法是获取一个函数指针并按原样调用它,如(假设someSelector返回一个float且没有参数); < / p>
SEL selector = NSSelectorFromString(@"someSelector");
float (*func)(id,SEL) = (float (*)(id,SEL))[someInstance methodForSelector: selector];
printf("return value is: %f", (func)(someInstance, selector));
答案 3 :(得分:3)
旧问题的新答案〜
从performSelector
NSInvocationOperation *invo = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(height) object:nil];
[invo start];
CGFloat f = 0;
[invo.result getValue:&f];
NSLog(@"operation: %@", @(f));
其中
- (CGFloat)height {
return 42;
}
输出
2017-03-28 16:22:22.378 redpacket[46656:7361082] operation: 42
答案 4 :(得分:2)
我尝试按照dizy的建议实现NSInvocation,它按预期工作。
我也尝试过另一种方式,即
int result = objc_msgSend([someArray objectAtIndex:0], @selector(currentPoint));
在上面的例子中,我们绕过编译器并显式地插入objc_msgSend调用,如博客中所述: http://www.cocoawithlove.com/2011/06/big-weakness-of-objective-c-weak-typing.html
在这种情况下,我收到以下警告: 隐式声明类型为'id(id,SEL,...)'的库函数'objc_msgSend' 这是显而易见的,因为我们直接调用库函数。
所以,我实现了NSInvocation,这对我来说非常好。