我的iPad应用程序与XML Feed同步,在NSOperationQueue执行的NSOperation子类中运行同步。当它解析feed时,它通过performSelectorOnMainThread:withObject:waitUntilDone:
回调主线程来更新UI的各个部分,安排下载等。其中一些非常昂贵;随着同步的进行,UI有时会在一两秒内无响应。
为了使用户界面更具响应性,我删除了performSelectorOnMainThread:withObject:waitUntilDone:
的使用,转而使用直接调用来执行所有与同步相关的任务,包括更新用户界面。所以现在同步完全发生在NSOperationQueue创建的后台线程上。这似乎工作得很好,并且在同步期间UI的响应速度更快。
然而,我很抱歉以这种方式释放它。我在各个地方看到过一些人应该只更新主线程(example with reference to AppKit)上的UI。但是我在文档中找不到关于这个主题的具体内容。
那么更新主线程上的UI有多重要?应用程序的哪些部分是线程安全的,哪些不是?是否有一个参考解释在NSOperation中执行什么是安全的,哪些应该只在iOS的主线程上执行?我真的在做一些不安全或容易崩溃的事情吗?
答案 0 :(得分:8)
始终更新主线程上的UI非常重要。从后台线程触摸UI可能会导致各种问题,包括内部状态损坏,崩溃或只是简单的错误行为。任何不需要触摸UI的工作都应该在后台线程上进行,但是更新UI的代码位必须在主线程上进行。
答案 1 :(得分:4)
Thread Safety Summary中的Threading Programming Guide讨论哪些基础类是线程安全的,哪些不是。对于常见问题的快速回答,整个摘要值得一试。
线程编程指南还有一个关于Threads and Your User Interface的非常简短的部分,其中“建议您接收与用户相关的事件并从应用程序的主线程启动接口更新”和“某些框架,例如Cocoa通常需要这种行为。“没有对这个Cocoa需求的讨论的交叉引用,但我想我最终会遇到它。
但结果是,根据这个文档,在主线程上执行UI更新很重要。
答案 2 :(得分:1)
您确定需要NSOperation吗? NSXMLParser.parse和NSURLConnection.start已经异步。如果您正在解析的类更新某个模型对象,并且您的视图控制器使用KVO观察该模型对象,您可能会得到更简单,性能更好的代码。
答案 3 :(得分:0)
技术说明中还有与ListAdder示例代码一起提供的进一步文档和讨论。这是TN2109:'简单可靠的NSOperation线程'。它反复讨论只从主线程更新UIKit元素,并给出正确和错误实现的示例。您可以通过搜索“线程限制”找到对它的进一步引用。