Возвращаемое значение для executeSelector: - PullRequest
36 голосов
/ 27 июня 2011

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

Ответы [ 5 ]

79 голосов
/ 11 июня 2012

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

Я думаю, вы не можете получить возвращаемое значение от executeSelector.Вы должны посмотреть на NSInvocation.

4 голосов
/ 28 марта 2017

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

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

3 голосов
/ 23 января 2015

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

SEL selector = NSSelectorFromString(@"someSelector");
float (*func)(id,SEL) = (float (*)(id,SEL))[someInstance methodForSelector: selector];
printf("return value is: %f", (func)(someInstance, selector));
2 голосов
/ 23 апреля 2015

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

...