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