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

时间:2011-01-12 18:05:05

标签: objective-c multithreading cocoa-touch uikit

我有一个应用程序,它使用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];
}

2 个答案:

答案 0 :(得分:10)

  

“试图从a获取网络锁定   主线程以外的线程或   网络线程UIKit不应该   从辅助线程调用“

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

假设parseDidComplete是消息来源的地方,那么类似的东西将“起作用”:

[delegate performSelectorOnMainThread: @selector(parseDidComplete) withObject: nil waitUntilDone: YES];

“工作”,因为线程很难,这个答案完全忽略了你可能遇到的任何同步问题。

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

答案 1 :(得分:1)

我怀疑这一行:

[delegate parseDidComplete];

如果委托类与UIKit组件交互,那么检索XML内容的后台线程就会调用必须全部位于主线程中的前端对象。

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