Возвращаемое значение для executeSelector:
Каково будет возвращаемое значение для executeSelector: если я передам селектор, который возвращает тип примитива (для объекта), такой как 'week' для NSDateComponents (который будет возвращать int)?
5 ответов
Пример использования 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);
}
Я думаю, что вы не можете получить возвращаемое значение от executeSelector. Вы должны посмотреть в NSInvocation
,
Новый ответ на старый вопрос ~
Существует более краткий способ получения возвращаемого значения из 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
Чтобы ответить на вторую часть вопроса, другой способ вызвать селектор, который возвращает примитив, состоит в том, чтобы получить указатель на функцию и вызвать его как таковой, как в (при условии, что someSelector возвращает число с плавающей точкой и не имеет аргументов);
SEL selector = NSSelectorFromString(@"someSelector");
float (*func)(id,SEL) = (float (*)(id,SEL))[someInstance methodForSelector: selector];
printf("return value is: %f", (func)(someInstance, selector));
Я попробовал NSInvocation, реализованный в соответствии с предложением dizy, он работал как положено.
Я также попробовал другой способ, т.е.
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, который прекрасно работает для меня.