如何根据线程动态使用MOC来保护核心数据

时间:2013-10-04 17:25:07

标签: ios multithreading core-data concurrency

我已阅读有关核心数据和线程的材料,并了解每个线程的单独MOC的原理。我的问题是,动态确定是使用不同MOC还是主要MOC的最佳方法是什么。我有一些方法有时在主线程上调用,有时在后台调用。动态检测线程不推荐还是没关系?任何陷阱?或者人们只是为后台进程编写单独的方法?

一些额外的细节......我有一个刷新过程,它使用一个简单的performSelectorInBackground执行主线程的一系列更新(因此在用户等待时不会锁定UI)。这个过程通过串行移动,所以我不必担心在这个线程上访问数据库的多个事情,显然诀窍是保持主要和背景安全。我已经实现了使用单独的上下文并在其他地方合并,但我最近重新构建,现在我使用的方法在我之前没有。所以我想重写那些,使用单独的上下文,但有时候在主线程上遇到它们并且可以正常访问主MOC。

3 个答案:

答案 0 :(得分:1)

您没有详细说明如何管理后台操作以及您正在使用它做什么,因此很难提出任何建议。

通常,由于创建MOC是一种非常快速的操作,因此每次在只读模式下需要创建MOC时(例如,用于数据查找),您可以创建新的临时MOC。如果您还有更新(例如,添加新对象或修改现有对象),则应考虑合并的成本,因此每次创建临时MOC都不是一个好方法。 另一个好方法可能是在后台线程中创建子上下文。 但是,正如我所说,这一切都取决于你在做什么。

看看这篇关于多线程核心数据使用情况的好文章:Multi-Context CoreData。它描述了几个场景及其解决方案。

编辑:

您当然可以使用isMainThread区分这两种情况(您可以使用主MOC以及何时需要新MOC)。这就是该方法的用途(而且肯定不贵)。

另一方面,如果你想要一个更清洁的实现,最好的方法IMO将创建一个子MOC(它简化了很多合并过程 - 它几乎是自动的,因为你只需要在保存后保存父上下文临时背景)。

答案 1 :(得分:1)

每个线程都需要一个新的NSManagedObjectContext,并且您需要从该线程的新MOC创建NSManagedObject的新版本。阅读@ sergio关于该方法的优缺点的答案。

要检查您是否在主线程上,可以使用[NSThread isMainThread]并以此方式进行确定。或者,当您在CoreData上启动一个新线程时,也要创建一个新的MOC。

答案 2 :(得分:0)

一种常见的方法是将每个托管对象上下文与特定的串行调度队列相关联。所以主队列有一个,否则你可以动态创建它们。

将这些内容绑定到队列后,可以使用dispatch_queue_set_specific将特定上下文附加到特定队列,并使用dispatch_get_specific获取当前队列的上下文。它们都出现在iOS 5中,所以你会看到一些与iOS 4兼容的代码,它们会跳过更复杂的环节,但你真的不必再担心了它。

或者,如果您的上下文对特定的NSRunLoopNSThread感到厌倦,请将上下文存储到[[NSThread currentThread] threadDictionary] - 这正是它的用途。