41

performSelector 的返回值是什么:如果我传递一个返回原始类型(在对象上)的选择器,例如 NSDateComponents 上的“星期”(它将返回一个 int)?

4

5 回答 5

85

使用 NSInvocation 返回浮点数的示例:

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);
}
于 2012-06-11T02:07:17.787 回答
9

我认为您无法从 performSelector 获取返回值。你应该调查一下NSInvocation

于 2011-06-27T11:23:18.190 回答
6

老问题的新答案~

有一种更简洁的方法可以从中获取返回值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

于 2017-03-28T09:03:05.290 回答
3

为了回答问题的第二部分,调用返回原语的选择器的另一种方法是获取函数指针并按原样调用它,例如(假设 someSelector 返回一个浮点数并且没有参数);

SEL selector = NSSelectorFromString(@"someSelector");
float (*func)(id,SEL) = (float (*)(id,SEL))[someInstance methodForSelector: selector];
printf("return value is: %f", (func)(someInstance, selector));
于 2015-01-23T03:40:34.193 回答
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

在这种情况下,我收到以下警告: 隐式声明库函数 'objc_msgSend' 类型为 'id (id, SEL, ...)' 这很明显,因为我们直接调用库函数。

所以,我使用 NSInvocation 来实现,这对我来说非常好。

于 2015-04-23T10:37:32.433 回答