objective c - Valor de retorno para performSelector:
objective-c cocoa-touch (5)
¿Cuál será el valor de retorno para performSelector: si paso un selector que devuelve un tipo primitivo (en objeto), como ''week'' en NSDateComponents (que devolverá un int)?
Creo que no puedes obtener el valor de retorno de performSelector. Debería ver NSInvocation
.
Nueva respuesta a la vieja pregunta ~
Hay una forma más concisa de obtener el valor de retorno de performSelector
NSInvocationOperation *invo = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(height) object:nil];
[invo start];
CGFloat f = 0;
[invo.result getValue:&f];
NSLog(@"operation: %@", @(f));
en el cual
- (CGFloat)height {
return 42;
}
salida
2017-03-28 16:22:22.378 redpacket[46656:7361082] operation: 42
Para responder a la segunda parte de la pregunta, otra forma de invocar un selector que devuelve una primitiva sería obtener un puntero de función e invocarlo como tal, como en (asumiendo que someSelector devuelve un flotante y no tiene argumentos);
SEL selector = NSSelectorFromString(@"someSelector");
float (*func)(id,SEL) = (float (*)(id,SEL))[someInstance methodForSelector: selector];
printf("return value is: %f", (func)(someInstance, selector));
Probé NSInvocation implementado como lo sugirió dizy, está funcionando como se esperaba.
También probé de otra manera, es decir
int result = objc_msgSend([someArray objectAtIndex:0], @selector(currentPoint));
en el caso anterior, estamos eludiendo el compilador e insertando objc_msgSend explícitamente como se describe en el blog: http://www.cocoawithlove.com/2011/06/big-weakness-of-objective-c-weak-typing.html
En este caso, recibí la siguiente advertencia: declarar implícitamente la función de la biblioteca ''objc_msgSend'' con el tipo ''id (id, SEL, ...)'' que es obvio porque estamos llamando a la función de biblioteca directamente.
Entonces, implementé con NSInvocation, que funciona perfectamente bien para mí.
Un ejemplo de uso de NSInvocation para devolver un flotante:
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);
}