Return value for performSelector:

走远了吗. 提交于 2019-11-28 17:48:37

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

joshbodily

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!