Ios 如何使用具有参数的函数调用performSelectorInBackground?

Ios 如何使用具有参数的函数调用performSelectorInBackground?,ios,objective-c,performselector,Ios,Objective C,Performselector,对不起,我问了个新手问题(也许)。我正在为ios开发一个应用程序,我正在尝试执行一个从主线程读取的外部xml,以便在调用发挥神奇作用时不会冻结ui 这是我所知道的使进程不在目标c的主线程中执行的唯一方法 [self performSelectorInBackground:@selector(callXml) withObject:self]; 所以我把我的调用合并到一个函数中 - (void)callXml{ [RXMLElem

对不起,我问了个新手问题(也许)。我正在为ios开发一个应用程序,我正在尝试执行一个从主线程读取的外部xml,以便在调用发挥神奇作用时不会冻结ui

这是我所知道的使进程不在目标c的主线程中执行的唯一方法

[self performSelectorInBackground:@selector(callXml)
                           withObject:self];
所以我把我的调用合并到一个函数中

 - (void)callXml{
     [RXMLElement elementFromURL:[NSURL URLWithString:indXML]];
 }
现在我必须将字符串indXML作为函数的参数,以便根据需要调用不同的xml。 差不多

 - (void)callXml:(NSString *) name{
     [RXMLElement elementFromURL:[NSURL URLWithString:indXML]];
 }
在这种情况下,对performSelector的调用如何更改?如果我以通常的方式执行此操作,则会出现语法错误:

[self performSelectorInBackground:@selector(callXml:@"test")
                           withObject:self];
ie:作为withObject:传入的内容将成为方法的参数

有趣的是,这里介绍了如何使用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];
    });
});
为此

- (void)callXml:(NSString *) name{
     [RXMLElement elementFromURL:[NSURL URLWithString:indXML]];
 } 
你可以这样打电话

  [self performSelectorInBackground:@selector(callXml:)
                               withObject:@"test"];

如果您的方法有参数,则与方法一起使用,并将参数作为withObject参数传递,因为
performSelectorInBackground:withObject:
只接受一个object参数。绕过此限制的一种方法是将参数字典(或数组)传递给“包装器”方法,该方法解构参数并调用实际方法。

您使用的选择器需要与方法名称完全匹配-方法名称包括冒号(:)字符。因此,您的选择器应该是:

@selector(callXml:)
如果要传递参数

如果需要传递更复杂的数据,有3个选项:

  • 传递包含参数的
    NSArray
    NSDictionary
  • 将包含所有必需数据的自定义对象作为属性传递
  • 使用GCD()
  • 嗨,试试这个

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

    传递NSString是可以的。。。参见其他答案3。选项将传递一个自定义对象,该对象包含所有需要的参数。酷!如果函数返回我需要得到的东西呢?(例如,return[RXMLElement等…])如果你想从方法中得到被调用的方法应该返回一些东西,即使用返回类型而不是void.ex-(返回类型)callXml:(NSString*)name{}k@Elisabettafalivene如果你想将它存储在某个变量中,那么键入var_name=[self method];然后被调用的方法将返回一些值@Elisabettafalivene这是我猜测的,但当我调用(RXMLElement*)调用XML:(NSString*)xmlName{return[RXMLElement elementFromURL:[NSURL URLWithString:xmlName]];}和RXMLElement*rootXML=nil;rootXML=[self-performSelectorInBackground:@selector(callXml),对象为indXMLdateAggiornamento];它开始说“从不兼容的类型“void”分配给“rxmlement*”,您能告诉我这一行[rxmlement elementFromURL:[NSURL URLWithString:indXML]]的返回类型吗;?它将是(RXMLElement*)???第二种方式,代码将在主线程之外执行,而不会扰乱ui流?是的。看见“并发队列(也称为一种全局调度队列)同时执行一个或多个任务,但任务仍按添加到队列的顺序启动。当前正在执行的任务在调度队列管理的不同线程上运行。在任何给定点执行的任务的确切数量是可变的,取决于系统条件。“我仍在猜测该怎么做。”。我仍然无法按照您建议的方式使用performSelector,这给我带来了一个异常,但我确实解决了放弃performSelector并使用dispatch_async的问题。成交!;)尝试performSelector的方法来解决您的问题:在“NSInvalidArgumentException”+[funzioni callXml:])中,注意“+”。这意味着它正在寻找类方法(
    +(void)callXml:
    )而不是实例方法(
    -(void)callXml
    :),这意味着您是从类方法而不是实例方法中调用performSelector…它抛出一个错误:由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'**-[NSThread initWithTarget:selector:object:]:目标未实现选择器(***+[funzioni callXml:])----其中“funzioni”是我的类。我试图在my.m和my.h.No fortune中定义函数。@ElisabettaFalivene Mike Pollard已经向您展示了如何从后台线程更新UI。使用GCD?是的,这就是我选择他的答案的原因。这个问题对我来说已经解决了,但我对解决performSelector的问题很好奇。^^^不过这并不重要,所以我放弃。@ElisabettaFalivene:Bhargavi根据您提供的所有信息给出了正确的答案。您的错误与您的问题不一致。您的错误(它试图调用一个类方法,即您正在调用它的对象,
    self
    是一个类)指示您正在从类方法进行调用。如果是这种情况,那么您以前在调用
    callXml
    时所做的操作(如果从同一位置调用)也在调用类方法。但是,在您的问题中,您将
    callXml
    callXml:
    显示为实例方法。
     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]];
     }