为什么我应该为每个新线程或NSOperation创build一个NSManagedObjectContext,而不是在主线程上调用Core Data?

一些开发人员已经告诉我,我可以为每个新线程创build一个新的NSManagedObjectContext实例,以使Core Data线程安全。 那么我只好照顾之后的合并。

对我来说,这听起来像是很多额外的代码和开销。

是否有这个解决scheme不好的原因? 它来了:

而不是为每个新线程或每个NSOperation创build一个新的MOC,我将在主线程上执行MOC-更改,就像我们从UIKit知道的一样。 我只是调用-performSelectorOnMainThread:...waitUntilDone:YES并摆脱所有的核心数据并发问题。

优点: – 不必为每个Thread / NSOperation创build一个新的MOC。 – 不必将MOC合并在一起。 – 确保没有并发问题,因为核心数据保持在主线程安全的地方。

缺点: – 调用像-performSelectorOnMainThread:...waitUntilDone:YES看起来丑陋,难以阅读。 – 线程/ NSOperation被阻止。 但实际上,系统无论如何不能一次做多件事情。 就我而言,核心数据部分不是性能瓶颈。 围绕它的繁重计算是在后台线程或NSOperation中进行的。

你怎么看? 这值得探索吗? 为什么你仍然喜欢为每个新的线程/ NSOperation创build一个MOC,然后处理合并? 相比于在主线程上做这个,这有什么好处呢?

“磁盘访问非常昂贵” – 我们被告知…

如果您获取或保存大量数据,则在NSThread / NSOperation上使用单独的MOC是有好处的。 再加上视图转换,这可以很好地改善应用程序中“速度”的感觉,因为主线程只能执行UI转换。

我想你可以通过测量你实际花费多less时间来访问你的商店和你的UI响应(IIRC:试用CoreData和CoreAnimation工具),并比较两种情况:使用每个线程的不同MOC与调用-performSelectorOnMainThread:...waitUntilDone:YES

顺便说一句,如果你保存在后台线程,你还需要考虑当保存操作正在进行时,你的应用程序被终止会发生什么。 后台线程立即死亡,而看门狗等待5秒钟完成主线程。

在后台线程/操作上执行密集操作的主要原因是UI在front / main-thread上运行。 如果您在主线程上运行密集的Core Data操作,则UI将无响应,并可能使用户认为应用程序挂起或崩溃。 由于大多数应用程序在密集工作时都显示至less有一些动作,所以用户已经接受了预期无响应或静态UI指示崩溃或挂起的训练。

移动用户也对等待时间更加敏感。 如果你坐在办公桌前啜饮一杯咖啡,45秒的停顿似乎并不长。 如果你正在通过一个机场,它确实。

从主线程删除密集的操作允许用户界面继续运行。 在某些情况下,这意味着用户可以继续工作,而在其他情况下,这意味着您可以dynamic更新UI以传达应用程序正在进行密集操作,这就是用户必须等待的原因。

这对用户如何看待您的应用的质量和可用性产生重大影响。

话虽如此,直到您testing应用程序并发现Core Data无法在主线程上处理处理之前,我不会再为使用后台线程/操作而烦恼。 在绝大多数情况下,它可以。 从服务器下载缓慢可能是后台操作需求的主要驱动因素。 如果你没有这些,很可能你的应用程序不需要任何严肃的背景。