Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

respondsToSelector with different argument types in selector

Suppose we have different Object which have the same method name but with differet argument types like: getMethod:(NSNumber*)aNumber and getMethod:(NSString*)aString.

How to check with respondsToSelector or through other way, if an object responds to the selector with particular argument type, something like this:

[myObjectA respondsToSelector:@selector(getMethod:(NSNumber*))]

How do you do this? Thanks.

like image 348
Oleg Danu Avatar asked Feb 12 '13 10:02

Oleg Danu


2 Answers

You have a couple of ways to find type names of arguments for selector. For example this code will work:

Method method = class_getInstanceMethod([self class], @selector(someMethod:param2:param3:));
char type[256];
int argsNumber = method_getNumberOfArguments(method);
for (int i = 0; i < argsNumber; i++) {
    method_getArgumentType(method, i, type, 256);
    NSLog(@"%s", type);
}

First and second log arguments are system and you are not interested in them, so another tree lines are that you need.

also code below will give you same result

NSMethodSignature *sig = [self methodSignatureForSelector:@selector(someMethod:param2:param3:)];
int args = [sig numberOfArguments];
for (int i = 0; i < args; i++) {
    NSLog(@"%s", [sig getArgumentTypeAtIndex:i]);
}

someMethod:param2:param3: can have implementation like this for example

- (BOOL) someMethod:(NSString *)str param2:(UIView *)view param3:(NSInteger)number
{
    return NO;
}

BUT! Of cause we have big but here )) In both cases you will have arguments types names with const char * string with length a one symbol. Compiler encodes types name as described here. You can differ int from char but not UIView from NSString. For all id types you will have type name '@' that means it's id. Sad but true. Unfortunately I've not found any ways to get whole complete type name or decode given. If you will find this way let me know pls.

So this is solution. Hope you will find the way how to use this approach in your project.

like image 142
Rostyslav Druzhchenko Avatar answered Sep 28 '22 07:09

Rostyslav Druzhchenko


You wont actually be able to distinguish the methods parameter type but maybe you could do something like this instead:

if([myObject isKindOfClass:[A class]])
     [myObjectA getMethod:aNumber];
else if([myObject isKindOfClass:[B class]])
     [myObjectA getMethod:aString];

You wont need to check if it responds to the selector since you have checked that its the right type. Maybe your problem is more complicated than this but this should work if its not.

like image 27
Fonix Avatar answered Sep 28 '22 06:09

Fonix