Cocoa touch 在NSO操作中使用'performSelectorOnMainThread:withObject:waitUntilDone:'有多重要?

Cocoa touch 在NSO操作中使用'performSelectorOnMainThread:withObject:waitUntilDone:'有多重要?,cocoa-touch,ios,concurrency,uikit,nsoperation,Cocoa Touch,Ios,Concurrency,Uikit,Nsoperation,我的iPad应用程序与XML提要同步,在从NSOperationQueue执行的NSOperation子类中运行同步。在解析提要时,它通过performSelectorOnMainThread:withObject:waitUntilDone:回调主线程,以更新UI的各个部分,安排下载等。其中一些相当昂贵;当同步进行时,UI有时会在一两秒钟内失去响应 为了使UI更具响应性,我已经取消了使用performSelectorOnMainThread:withObject:waitUntilDone:,

我的iPad应用程序与XML提要同步,在从NSOperationQueue执行的NSOperation子类中运行同步。在解析提要时,它通过
performSelectorOnMainThread:withObject:waitUntilDone:
回调主线程,以更新UI的各个部分,安排下载等。其中一些相当昂贵;当同步进行时,UI有时会在一两秒钟内失去响应

为了使UI更具响应性,我已经取消了使用
performSelectorOnMainThread:withObject:waitUntilDone:
,而改用直接调用来执行所有与同步相关的任务,包括更新UI。因此,现在同步完全在NSOperationQueue创建的后台线程上进行。这似乎工作得很好,而且在同步过程中,UI的响应速度要快得多

然而,我对用这种方式发布它持谨慎态度。我在不同的地方看到一些人提到,应该只更新主线程()上的UI。但是我在文档中找不到关于这个主题的任何具体内容


那么更新主线程上的UI有多重要呢?应用程序的哪些部分是线程安全的,哪些部分不是?是否有参考资料解释了在NSO操作中执行哪些操作是安全的,哪些操作应该只在iOS的主线程上执行?我真的在做不安全或容易崩溃的事情吗?

始终在主线程上更新UI是非常重要的。从后台线程触摸UI可能会导致各种问题,包括内部状态损坏、崩溃,或者仅仅是不正确的行为。任何不需要触摸UI的工作都应该在后台线程上进行,但是更新UI的代码位肯定需要在主线程上进行。

您确定需要NSO操作吗?NSXMLParser.parse和NSURLConnection.start已经是异步的。如果你解析的类更新了一些模型对象,而你的视图控制器使用KVO观察模型对象,那么你可能会得到更简单、性能更好的代码。对于常见问题的快速回答,整个摘要值得略读一下

《线程编程指南》也有一个非常简短的章节,其中“建议您从应用程序的主线程接收与用户相关的事件并启动界面更新”,以及“一些框架(如Cocoa)通常需要此行为。”没有交叉引用对此Cocoa要求的讨论,但我想我最终会遇到它


但结果是,根据本文档,在主线程上执行UI更新非常重要。

ListAdder示例代码附带的技术说明中有进一步的文档和讨论。它是TN2109:“简单可靠的线程操作”。它反复讨论仅从主线程更新UIKit元素,并给出了正确和错误实现的示例。你可以通过搜索“线程限制”来找到更多的参考资料。

一篇相关的帖子也提出了同样的问题,其中包括一些提交给苹果的错误报告,要求澄清:,一定有一些众所周知的最佳实践,我想没有,但WTF有记录吗?我只是有一种感觉,它是从各种来源的情况,但没有权威…我实际上不确定。它必须记录在某个地方,但我不知道在哪里。这就是我的想法。我很想仔细阅读它,不管它在哪里……一般来说,如果文档没有说它是线程安全的,那么它通常不是。您知道UI已经被从主线程访问了。因此,假设UI应该只在主线程上访问是相当安全的。如果你遇到了明确的文档,请一定要告诉我。我找到了一些文档,并在一个单独的答案中链接到它们。谢谢是的,我肯定。我使用的是libxml2,不是NSXMLParser。而且没有模型本身。