How to call performSelectorInBackground with a function having arguments?
Solution 1
[self performSelectorInBackground:@selector(callXml:)
withObject:@"test"];
ie: what you pass in as withObject: becomes the parameter to your method.
Just as a point of interest here's how you could do it using GCD:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self callXml:@"test"];
// If you then need to execute something making sure it's on the main thread (updating the UI for example)
dispatch_async(dispatch_get_main_queue(), ^{
[self updateGUI];
});
});
Solution 2
For this
- (void)callXml:(NSString *) name{
[RXMLElement elementFromURL:[NSURL URLWithString:indXML]];
}
You can call like this
[self performSelectorInBackground:@selector(callXml:)
withObject:@"test"];
If your method has parameter then : is used with method_name and pass parameter as withObject argument
Solution 3
Hi try this,
RXMLElement *rootXML= [self performSelectorInBackground:@selector(callXml:)
withObject:@"test"];
- (RXMLElement *)callXml:(NSString *) name{
NSLog(@"%@",name);//Here passed value will be printed i.e test
return [RXMLElement elementFromURL:[NSURL URLWithString:indXML]];
}
Solution 4
The selector you use needs to be an exact match to the method name - the method name includes the colon (:) characters. So your selector should be:
@selector(callXml:)
If you want to pass a parameter.
If you need to pass more complex data, you have 3 options:
- Pass an
NSArray
orNSDictionary
containing the parameters - Pass a custom object which contains all of the required data as attributes
- Use GCD (GCD_libdispatch reference)
Sasha Grievus
Updated on July 28, 2022Comments
-
Sasha Grievus almost 2 years
Sorry for the newbie question (maybe). I'm developing an app for ios and i'm trying to execute an external xml reading out of the main thread in order not to freeze the ui while the call is doing its magic.
This is the only way i know to made a process not to execute in the main thread in objective c
[self performSelectorInBackground:@selector(callXml) withObject:self];
so i did incapsulate my call into a function
- (void)callXml{ [RXMLElement elementFromURL:[NSURL URLWithString:indXML]]; }
Now i have to make the string indXML be a parameter of the function in order to call different xml as i need to. Something like
- (void)callXml:(NSString *) name{ [RXMLElement elementFromURL:[NSURL URLWithString:indXML]]; }
In this case, how the call to performSelector change? If i do it in the usual way i get syntax errors:
[self performSelectorInBackground:@selector(callXml:@"test") withObject:self];
-
Mike Pollard about 11 yearsPassing an NSString is fine... see the other answers
-
Sasha Grievus about 11 yearscool! and what if the function return something i need to get? (i.e. return [RXMLElement etc.....])
-
Sasha Grievus about 11 yearsIn the second way the code will be execute out of the main thread without messing up with the ui flow?
-
Sugan S about 11 yearsif u want to get from method that called method should return something i.e instead of void use your return type.ex - (return type)callXml:(NSString *) name { } k @ElisabettaFalivene
-
Mike Pollard about 11 yearsYes. See here ... "Concurrent queues (also known as a type of global dispatch queue) execute one or more tasks concurrently, but tasks are still started in the order in which they were added to the queue. The currently executing tasks run on distinct threads that are managed by the dispatch queue. The exact number of tasks executing at any given point is variable and depends on system conditions."
-
Mert about 11 years3. Option would be passing a custom object, which contains all needed params.
-
Sugan S about 11 yearsif u want to store it in some variable then type var_name=[self method];then the called method will return some value. @ElisabettaFalivene
-
Sasha Grievus about 11 yearsIt's what i was guessing but when i did - (RXMLElement *)callXml:(NSString *) xmlName{ return [RXMLElement elementFromURL:[NSURL URLWithString:xmlName]]; } and RXMLElement *rootXML=nil; rootXML = [self performSelectorInBackground:@selector(callXml) withObject:indXMLdateAggiornamento]; it began saying "Assigning to 'RXMLElement *' from incompatible type 'void'"
-
Sugan S about 11 yearscan u tell me what typ will be return for this line [RXMLElement elementFromURL:[NSURL URLWithString:indXML]];? it will be of type (RXMLElement *)???
-
Sugan S about 11 yearshey just use return [RXMLElement elementFromURL:[NSURL URLWithString:indXML]]; in your code
-
Sugan S about 11 yearsRXMLElement *rootXML=[self performSelectorInBackground:@selector(callXml:) withObject:@"test"];
-
Sugan S about 11 yearshi friend check my updated answer and let me know @ElisabettaFalivene
-
Sugan S about 11 years
-
Sugan S about 11 yearsjust try this RXMLElement* var ; - (void)callXml:(NSString *) name{ var= [RXMLElement elementFromURL:[NSURL URLWithString:indXML]]; NSLog("%@",var); } and post what u get in consol @ElisabettaFalivene
-
Sasha Grievus about 11 yearsIt throws an error: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSThread initWithTarget:selector:object:]: target does not implement selector (*** +[funzioni callXml:])' ----- where "funzioni" is my class. I tried to define the function in my .m and in my .h. No fortune.
-
Sasha Grievus about 11 yearsI was still guessing what to do. I have still problem using the performSelector for the way you suggested to use it throws me an exception, but it's true i've solved the problem abandoning performSelector and using dispatch_async. Deal! ;)
-
βhargavḯ about 11 years@ElisabettaFalivene Mike Pollard already shown you how to update UI from background thread.
-
Sasha Grievus about 11 yearsusing GCD? Yes, that's why i choose his answer. The problem is solved for me, but i was curios of solving the issue i had with performSelector. ^^' It's not so important, though, so i give up.
-
Mike Pollard about 11 yearsJust picking up on your problem trying the performSelector way: In the 'NSInvalidArgumentException' +[funzioni callXml:]) note the '+'. It means it's looking for a class method (
+(void)callXml:
) not an instance method (-(void)callXml
: ) implying that you were calling performSelector from within a class method rather than an instance method... -
newacct about 11 years@ElisabettaFalivene: Bhargavi gave the correct answer based on all the information you gave. Your error is inconsistent with your question. Your error (that it is trying to call a class mehtod, i.e. the object you are calling it on,
self
is a class) indicates that you are making the call from a class method. If that were the case, then what you were doing previously (if called from the same place) when callingcallXml
was also calling a class method. However, in your question, you showedcallXml
andcallXml:
as instance methods.