1

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

一些额外的细节......我有一个刷新过程,它使用一个简单的 performSelectorInBackground 在主线程之外执行一堆更新(所以不要在用户等待时锁定 UI)。这个过程通过连续的步骤移动,所以我不必担心在这个线程上访问数据库的多个东西,显然诀窍是保持主和后台的安全。我已经使用单独的上下文实现并在其他地方合并,但我最近重新架构,现在在后台使用我以前没有的方法。所以我想重写那些,使用单独的上下文,但有时会在主线程上击中它们并且可以很好地访问主 MOC。

4

3 回答 3

1

您没有提供有关如何管理后台操作以及使用它做什么的详细信息,因此很难提出任何建议。

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

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

编辑:

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

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

于 2013-10-04T17:46:17.760 回答
1

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

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

于 2013-10-04T17:51:08.120 回答
0

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

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

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

于 2013-10-04T19:33:33.250 回答