Objective C >> Is there a way to check the return value of the Selector?
let's say I have a selector that can be assigned to several different methods - each has a different return value.
Is there a way to check what is the return value of the method holding the selector before calling "performSelector"?
Is there a way to check what is the return value of the method holding the selector before calling "performSelector"?
Value? Not. A type? Jap. It seems that you want the return type of the method (or your question doesn't make sense).
Method m = class_getInstanceMethod([SomeClass class], @selector(foo:bar:));
char type[128];
method_getReturnType(m, type, sizeof(type));
Then you can check the returned type string in type
. For example "v"
means void (google full list).
you can use NSInvocation which is recommended by Apple Docs for this purpose
Here is some sample code for using 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);
}
If the method doesn't return an object (it returns a primitive type) then use NSInvocation instead.
@implementation NSObject(SafePerformSelector)
-(id) performSelectorSafely:(SEL)aSelector;
{
NSParameterAssert(aSelector != NULL);
NSParameterAssert([self respondsToSelector:aSelector]);
NSMethodSignature* methodSig = [self methodSignatureForSelector:aSelector];
if(methodSig == nil)
return nil;
const char* retType = [methodSig methodReturnType];
if(strcmp(retType, @encode(id)) == 0 || strcmp(retType, @encode(void)) == 0){
return [self performSelector:aSelector];
} else {
NSLog(@"-[%@ performSelector:@selector(%@)] shouldn't be used. The selector doesn't return an object or void", [self class], NSStringFromSelector(aSelector));
return nil;
}
}
@end
performSelector: always returns id
. The actual type returned is determined by the method you are calling; so there is no way to know this beforehand.