Подтвердить что ты не робот

Возвращаемое значение для функции "Спектр":

Какое будет возвращаемое значение для performSelector: если я передаю селектор, который возвращает примитивный тип (на объекте), например "неделя" на NSDateComponents (который вернет int)?

4b9b3361

Ответ 1

Пример использования 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);
}

Ответ 2

Я думаю, что вы не можете получить возвращаемое значение из функции performSelector. Вы должны заглянуть в NSInvocation.

Ответ 3

Чтобы ответить на вторую часть вопроса, другим способом вызвать селектор, который возвращает примитив, было бы получить указатель на функцию и вызывать его как таковое, как в (если someSelector возвращает float и не имеет аргументов);

SEL selector = NSSelectorFromString(@"someSelector");
float (*func)(id,SEL) = (float (*)(id,SEL))[someInstance methodForSelector: selector];
printf("return value is: %f", (func)(someInstance, selector));

Ответ 4

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

Ответ 5

Новый ответ на старый вопрос ~

Существует более сжатый способ получения возвращаемого значения из 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