Возвращаемое значение для 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, который прекрасно работает для меня.

Другие вопросы по тегам