Objective c 不应从辅助线程调用UIKit的错误消息

Objective c 不应从辅助线程调用UIKit的错误消息,objective-c,multithreading,cocoa-touch,uikit,Objective C,Multithreading,Cocoa Touch,Uikit,我有一个应用程序,它使用UISearchBar根据用户输入从外部API进行动态搜索 应用程序正在搜索外部API并正确显示结果,但当我从搜索结果中选择任何一行时,屏幕冻结,我收到此错误 试图从主线程或web线程以外的线程获取web锁 不应从次线程调用UIKit 我完全不知道我该怎么解决这个问题 这是代码 - (void) run: (id) param { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; N

我有一个应用程序,它使用UISearchBar根据用户输入从外部API进行动态搜索

应用程序正在搜索外部API并正确显示结果,但当我从搜索结果中选择任何一行时,屏幕冻结,我收到此错误

试图从主线程或web线程以外的线程获取web锁 不应从次线程调用UIKit

我完全不知道我该怎么解决这个问题

这是代码

- (void) run: (id) param  {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL: [self URL]];
    [parser setDelegate: self];
    [parser parse];
    [parser release];
    [delegate parseDidComplete];
    [pool release];
} 

- (void) parseXMLFile: (NSURL *) url
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [self setURL: url];
    NSThread* myThread = [[NSThread alloc] initWithTarget:self
                                                 selector:@selector(run
   object: nil];
    [myThread start];
    [pool release];
}

我怀疑这句话:

[delegate parseDidComplete];
如果委托类与UIKit组件交互,则检索XML内容的后台线程将调用前端对象,而前端对象必须全部位于主线程中


您可能希望了解如何使用NSOperation和NSOperationQueue执行异步操作。我相信这提供了一种更线程安全的方法来处理这种类型的用例。

我怀疑这句话:

[delegate parseDidComplete];
如果委托类与UIKit组件交互,则检索XML内容的后台线程将调用前端对象,而前端对象必须全部位于主线程中

您可能希望了解如何使用NSOperation和NSOperationQueue执行异步操作。我相信这提供了一种更线程安全的方法来处理这种类型的用例

试图从服务器获取web锁 主螺纹以外的螺纹或 不应使用web线程UIKit 从辅助线程调用

修复在概念上很简单;不要从线程更新UI

假设parseDidComplete是消息的来源,那么类似这样的方法将起作用:

[delegate performSelectorOnMainThread: @selector(parseDidComplete) withObject: nil waitUntilDone: YES];
工作,因为线程是困难的,这个答案完全忽略了您可能遇到的任何同步问题

请注意,最好使用NSOperation和NSOperationQueue。它们有很好的文档记录,并且有很多例子

试图从服务器获取web锁 主螺纹以外的螺纹或 不应使用web线程UIKit 从辅助线程调用

修复在概念上很简单;不要从线程更新UI

假设parseDidComplete是消息的来源,那么类似这样的方法将起作用:

[delegate performSelectorOnMainThread: @selector(parseDidComplete) withObject: nil waitUntilDone: YES];
工作,因为线程是困难的,这个答案完全忽略了您可能遇到的任何同步问题


请注意,最好使用NSOperation和NSOperationQueue。它们都有很好的文档记录,并且有很多示例。

如何获取API数据?看起来您是在另一个线程中异步执行此操作的。UIKit不是线程安全的,因此UI工作必须始终在主线程中完成。你能给我们一些相关的代码吗?这是代码;-void run:id param{NSAutoreleasePool池=[[NSAutoreleasePool alloc]init];NSXMLParser*parser=[[NSXMLParser alloc]initwithcontentsofull:[self URL]];[parser setDelegate:self];[parser parse];[delegate parsedidplete];}-void parseXMLFile:NSURL*URL{NSAutoreleasePool*pool=[[NSAutoreleasePool alloc]init];[self-setURL:url];NSThread-myThread=[[NSThread-alloc]initWithTarget:self-selector:@selectorrun-object:nil];[myThread-start];}我正在使用线程,以便在访问外部API时屏幕不会冻结。那么有没有什么方法可以解决UIKit线程问题呢??顺便说一句,我不明白这个问题到底意味着什么,不应该从辅助线程调用UIKit。对我来说,使用NSOperation和NSOperationQueue是绝对必要的,因为我必须从头开始学习?不使用这些就可以完成。如何获取API数据?看起来您是在另一个线程中异步执行此操作的。UIKit不是线程安全的,因此UI工作必须始终在主线程中完成。你能给我们一些相关的代码吗?这是代码;-void run:id param{NSAutoreleasePool池=[[NSAutoreleasePool alloc]init];NSXMLParser*parser=[[NSXMLParser alloc]initwithcontentsofull:[self URL]];[parser setDelegate:self];[parser parse];[delegate parsedidplete];}-void parseXMLFile:NSURL*URL{NSAutoreleasePool*pool=[[NSAutoreleasePool alloc]init];[self-setURL:url];NSThread-myThread=[[NSThread-alloc]initWithTarget:self-selector:@selectorrun-object:nil];[myThread-start];}我正在使用线程,以便在访问外部API时屏幕不会冻结。那么有没有什么方法可以解决UIKit线程问题呢??顺便说一句,我不明白这个问题到底意味着什么,不应该从辅助线程调用UIKit。对我来说,使用NSOperation和NSOperationQueue是绝对必要的,因为我必须从头开始学习?会是唐吗
你是对的。你可以在上面的答案中加上这个。你是对的。您可能想将其添加到上面的答案中。我不知道NSOperation和NSOperationQueue。您能否提供任何类似的NSOperation或NSOperationQueue示例供我参考;它提供了比我输入的更多的信息和更好的示例。@bbum如果您已经使用performSelectorOnMainThread实现了,那么使用NSOperation和Queue有什么好处?如果你写了一篇关于这个的博客文章,我会读它;Thx.我不知道NSOperation和NSOperationQueue。您能否提供任何类似的NSOperation或NSOperationQueue示例供我参考;它提供了比我输入的更多的信息和更好的示例。@bbum如果您已经使用performSelectorOnMainThread实现了,那么使用NSOperation和Queue有什么好处?如果你写了一篇关于这个的博客文章,我会读它;谢谢。