Core Data父级ManagedObjectContext是否需要与子级上下文共享一个并发types?

我可以将我的ManagedObjectContext的父上下文设置为具有不同并发types的ManagedObjectContext吗? 例如:

backgroundManagedObjectContext_ = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [backgroundManagedObjectContext_ setPersistentStoreCoordinator:coordinator]; managedObjectContext_ = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; [managedObjectContext_ setParentContext:backgroundManagedObjectContext_]; 

我的目标是(希望)快速保存managedObjectContext_(因为它只需要将内容保存到父内存中),然后让backgroundManagedObjectContext_在自己的队列上保存。 除非我碰巧需要在“前台”队列中做另一个保存,否则在后台保存我的用户应该永远不会看到很长的保存时间。

我遇到了看起来像是死锁的问题,但我不确定它们是否与此相关,或者如果我的问题在其他地方。


我可以或多或less地可靠地产生僵局的一个地方的细节:

我有一个主线程的托pipe对象上下文,它是由一个带有私有队列并发types的托pipe对象上下文来支持的,而且它有一个持久存储。

我有一些实体types(约5),每个实体types与另一个实体有一个或两个双向关系。

我的应用程序想要使用iCloud(我已经为这些testing拨了这个代码),所以它不能提供预填充数据库,当它检测到一个空数据库时,它需要build立它。

所以,当我看到一个空的数据库(这是在主线程上检查),我添加了大约4或8,除了其中一个实体types,最后一个约100(所有的增加发生在主线程)。 主线程执行saveContext。 在完成之后(没有错误),它会要求其他托pipe对象上下文运行一个也执行saveContext的块。 这个saveContext绝对是一个僵局参与者。 这也是“背景”NSManagedObjectContext完成的唯一的东西。

在这之后,确切的控制stream是有点模糊的,因为NSFetchedResultsController(一个给定的实体types(有〜3个成员),一个简单的sorting,批量大小为20左右)驱动下一轮的Core Data活动,但是TableViewController会调用它需要pipe理的项目数量,即“获取的结果控制器有多less结果”。 这个电话是僵局的另一面。 (所有这些都在主线程中)

根据我的经验,只要这两个上下文实现NSMainQueueConcurrencyTypeNSPrivateQueueConcurrencyType ,就不是必需的。 要记住的重要一点是,在跨多个线程交互托pipe对象上下文时,发送到上下文的所有消息都必须通过-performBlock:performBlockAndWait:来发送。

在最近的一个项目中,我有一个父NSManagedObjectContext ,它支持使用NSMainQueueConcurrencyType创build的NSMainQueueConcurrencyType 。 从那里我创build了一个带有NSPrivateQueueConcurrencyTypeNSManagedObjectContext ,并使用NSMainQueueConcurrencyType作为父级来设置上下文。 现在,当添加一个新的对象时,我的子上下文可能包含可丢弃的编辑,最终最终会在由父上下文支持的NSFetchedResultsController支持的表视图中结束。 当我准备好保存我的编辑并将其提升到父上下文时,代码如下所示。

 // Save the child context first [childContext performBlock:^{ NSError *error = nil; [childContext save:&error]; // Save the changes on the main context [parentContext performBlock:^{ NSError *parentError = nil; [parentContext save:&parentError]; }]; }]; 

现在我不能肯定地说,这是做这件事的正确方法,因为目前关于这方面的文档相当稀less。 如果你能显示一些你认为造成死锁的代码,这可能会有所帮助。 如果您在开发者计划中,则可能要查看今年有关核心数据的WWDC会话video。 我相信Mac OS X有两个版本,iOS版本有两个版本,基本上它们都有相同的想法,但每个版本都包含独特的信息。