核心数据单一托管对象上下文和两个线程
Posted
技术标签:
【中文标题】核心数据单一托管对象上下文和两个线程【英文标题】:Core Data Single Managed Object Context and two threads 【发布时间】:2013-04-24 13:58:21 【问题描述】:想弄清楚这一点我快疯了。我正在开发一个从网络服务器同步数据的应用程序。有一个后台线程将数据从服务器拉到应用程序。同时,我正在对 UI 进行更改。 UI 上更改的值正在保存到前台的核心数据中。
在整个应用程序中,我每次创建一个 fetchController 时都会从应用程序委托中获取一个 managedObjectContext 。应用委托代码
- (NSManagedObjectContext *)managedObjectContext
if (__managedObjectContext != nil)
return __managedObjectContext;
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
__managedObjectContext = [[NSManagedObjectContext alloc] init];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
return __managedObjectContext;
现在的问题是我在尝试保存上下文时遇到错误。错误在代码中随机发生。一旦我对任何实体进行更改,我就会保存上下文。此外,我在每个实体中都有两种关系,一种是与它的孩子一对多,另一种与它的父母是对 - 一种。所有关系都有适当的逆。
我认为我在这里通过保持一个上下文在概念上做错了。您能否建议在后台和前台线程都在读取和写入 coredata 的情况下我应该如何管理上下文。谢谢。
【问题讨论】:
您正在使用线程限制初始化您的 MOC,因此您只能在创建它的线程上使用它……很可能是主线程。它本质上没有任何问题……但是您如何为后台保存创建 MOC?如果您使用的是相同的 MOC,那就是您的问题。阅读有关 Core Data 并发的文档。 【参考方案1】:托管对象上下文不是线程安全的,因此如果您在多个线程上使用相同的上下文而不考虑并发性——您将遇到重大问题。例如,崩溃和/或数据丢失,甚至可能是数据损坏。有几种方法可以解决这个问题:
在创建上下文时使用其中一种队列并发类型 - 请参阅 initWithConcurrencyType:
的文档。然后,每当您访问数据存储时,使用performBlock:
或performBlockAndWait:
来同步访问。
为后台线程创建一个新的托管对象上下文。使用NSManagedObjectContextDidSaveNotification
和mergeChangesFromContextDidSaveNotification:
保持多个上下文同步。
但无论你做什么,不要只在多个线程上使用一个托管对象上下文。
【讨论】:
以上是关于核心数据单一托管对象上下文和两个线程的主要内容,如果未能解决你的问题,请参考以下文章