【发布时间】:2012-01-15 11:37:51
【问题描述】:
我可以将 ManagedObjectContext 的父上下文设置为具有不同并发类型的 ManagedObjectContext 吗?例如:
backgroundManagedObjectContext_ = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[backgroundManagedObjectContext_ setPersistentStoreCoordinator:coordinator];
managedObjectContext_ = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[managedObjectContext_ setParentContext:backgroundManagedObjectContext_];
我的目标是(希望)为 managedObjectContext_ 快速保存(因为它只需要将内容保存到父内存上下文中),然后让 backgroundManagedObjectContext_ 在它自己的队列上进行保存。除非我碰巧需要在后台保存之前从“前台”队列中进行另一次保存,否则我的用户应该永远不会看到很长的保存时间。
我遇到了看起来像死锁的情况,但我不确定它们是否与此有关,或者我的问题是否在其他地方。
我可以或多或少可靠地产生死锁的地方的详细信息:
我有一个用于主线程的托管对象上下文,它由具有私有队列并发类型的托管对象上下文支持,并且具有持久存储。
我有几个实体类型(大约 5 个),每个实体类型都有一个或两个与另一个实体的双向关系。
我的应用想要使用 iCloud(我为这些测试拨了那个代码),所以它不能附带预先填充的数据库,它需要在检测到空数据库时构建它。
所以当我看到一个空数据库(在主线程上检查)时,我添加了大约 4 或 8 个实体类型,但其中一种实体类型除外,最后一个得到大约 100 个(所有添加都发生在主线程上)线)。主线程执行 saveContext。完成后(没有错误),它要求其他托管对象上下文运行一个也执行 saveContext 的块。这个 saveContext 绝对是一个死锁参与者。这也是唯一使用“背景”NSManagedObjectContext 完成的事情。
在此之后,确切的控制流有点模糊,因为 NSFetchedResultsController(所有给定的实体类型(有大约 3 个成员)都具有简单的排序,批量大小为 20 左右)驱动下一轮核心数据活动,但是来自 TableViewController 的调用询问它需要管理多少项目,即“获取的结果控制器有多少结果”。这个电话是僵局的另一面。 (所有这些都在主线程中)
【问题讨论】:
-
为了命名约定,我建议您删除代码中的“_”后缀。将上下文命名为
childContext/parentContext或child/parent。