Question

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];
Was it helpful?

Solution

[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];
    });
});

OTHER TIPS

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

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:

  1. Pass an NSArray or NSDictionary containing the parameters
  2. Pass a custom object which contains all of the required data as attributes
  3. Use GCD (GCD_libdispatch reference)

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]];
 } 

Since performSelectorInBackground:withObject: takes only one object argument. One way to get around this limitation is to pass a dictionary (or array) of arguments to a "wrapper" method that deconstructs the arguments and calls your actual method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top