What will the return value for performSelector: if I pass a selector that returns a primitive type (on object), such as 'week' on NSDateComponents (which will return an int)?
An example of using NSInvocation to return a 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);
}
I think you cannot get the return value from performSelector. You should look into NSInvocation
.
New answer to old question~
There is a more concise way of getting the return value from performSelector
NSInvocationOperation *invo = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(height) object:nil];
[invo start];
CGFloat f = 0;
[invo.result getValue:&f];
NSLog(@"operation: %@", @(f));
in which
- (CGFloat)height {
return 42;
}
output
2017-03-28 16:22:22.378 redpacket[46656:7361082] operation: 42
To answer the second part of the question, another way to invoke a selector that returns a primitive would be to get a function pointer and invoke it as such, as in (assuming someSelector returns a float and has no arguments);
SEL selector = NSSelectorFromString(@"someSelector");
float (*func)(id,SEL) = (float (*)(id,SEL))[someInstance methodForSelector: selector];
printf("return value is: %f", (func)(someInstance, selector));
I tried the NSInvocation implemented as suggested by dizy, its working as expected.
I also tried the another way i.e.
int result = objc_msgSend([someArray objectAtIndex:0], @selector(currentPoint));
in the above case, we are bypassing the compiler and inserting objc_msgSend call explicitly as described in the blog: http://www.cocoawithlove.com/2011/06/big-weakness-of-objective-c-weak-typing.html
In this case, I got the following warning: Implicitly declaring library function 'objc_msgSend' with type 'id (id, SEL, ...)' which is obvious because we are calling library function directly.
So, I implemented with the NSInvocation which is working perfectly fine for me.
来源:https://stackoverflow.com/questions/6492033/return-value-for-performselector