Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How set a method as argument of class method in objective-c

I'm having a problem writing a class method wich have a method has argument.

The function is inside the class "SystemClass.m/h"

//JSON CALL
+(void)callLink:(NSString*)url toFunction:(SEL)method withVars:(NSMutableArray*)arguments {
    if([self checkConnection])
    {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSData *datas = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
            [arguments addObject:datas];
            [self performSelectorOnMainThread:@selector(method:) withObject:arguments waitUntilDone:YES];
        });
    }else{
        [self alertThis:@"There is no connection" with:nil];
    }
}

What the function does is to call a JSON url, and give data to a Method

I use it like this:

[SystemClass callLink:@"http://www.mywebsite.com/call.php" toFunction:@selector(fetchedInfo:) withVars:nil];

but it crashes like this:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[SystemClass method:]: unrecognized selector sent to class 0x92d50'

May you help me please? I'm trying to found the solution anyway!

Thanks, Alex

like image 688
alexcanessa Avatar asked Oct 25 '12 12:10

alexcanessa


1 Answers

In you callLink method you already give a selector as argument (it's the argument called "method"). Moreover you need to add one more argument, because the "method" argument should be invoked from an object that implement this method (and in the example you give us, the applicaiton will try to call the method named "method" from SystemClass when you call :

[self performSelectorOnMainThread:method withObject:arguments waitUntilDone:YES];

Here self is the SystemClass and a such method doesn't seem to exist in SystemClass, that's why it is crashing). So add a target (an id object) to the arguments :

+(void)callLink:(NSString*)url forTarget:(id) target toFunction:(SEL)method withVars:(NSMutableArray*)arguments;

So for the following line you should just give the selector and call this selector on the target object :

[target performSelectorOnMainThread:method withObject:arguments waitUntilDone:YES];

And not :

[self performSelectorOnMainThread:@selector(method:) withObject:arguments waitUntilDone:YES];

Improvement :

Before calling the selector you should check if the target responds to the selector doing something like that (it'll prevent your application from crashing). Instead of doing this :

[target performSelectorOnMainThread:method withObject:arguments waitUntilDone:YES];

Do this :

if([target respondsToSelector:method])
{
  [target performSelectorOnMainThread:method withObject:arguments waitUntilDone:YES];
}
else
{
  //The target do not respond to method so you can inform the user, or call a NSLog()...
}
like image 200
Ashbay Avatar answered Oct 12 '22 08:10

Ashbay