5

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

2
  • This is not related to Xcode. Retagged. Commented Oct 25, 2012 at 12:50
  • a better solution now would be to use a block instead of selector, target, and arguments Commented Oct 25, 2012 at 18:00

1 Answer 1

5

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()... } 
Sign up to request clarification or add additional context in comments.

5 Comments

I changed but it still continues to crash! (I don't know if it's clear: I got a "ViewController.m" wich includes "SystemClass.h", and I want to invoke [SystemClass callLink..] in ViewController
If you call performSelectorOnMainThread on an object, the selector should exist in this object. I'll edit my answer.
ok (i.e. an UIViewController?) I pass it like NSObject, and put it instead of "self" ?
No, just pass an id as argument. The id will be any object you want. See my edit ;)
You're welcome. I've added a little improvement, you should take a look.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.