Question

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)?

Was it helpful?

Solution

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);
}

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top