假设我们在核心数据模型中有两个实体:部门和员工。
部门与员工是一对多的关系。
我有以下 ManagedObjectContexts:
- Root:连接到 Persistent Store Coordinator
- Main:与父 Root 的上下文
当我想创建一个员工时,我执行以下操作:
- 我在主上下文中有一个部门 - 我在主上下文中
创建一个员工
- 我将部门分配给员工的部门属性
- 我保存主上下文
- 我保存根上下文
这会在 Main 上下文和 Root 上下文中创建一个保留循环。
如果我在没有子上下文的情况下执行此操作(全部在 Root 上下文中),那么我可以通过调用refreshObject:mergeChanges
Employee 来打破保留循环。在我使用这两个上下文的情况下,我仍然可以使用该方法来打破 Main 上下文的循环,但我将如何打破 Root 上下文的循环?
旁注:这是一个描述我的问题的简单示例。在 Instruments 中,我可以清楚地看到分配的数量在增长。在我的应用程序中,我的上下文比一层更深,导致了更大的问题,因为我得到了一个新的实体分配,每个上下文都有保留周期,我正在保存。
15/04 更新:NSPrivateQueueConcurrencyType 与 NSMainQueueConcurrencyType
保存两个上下文后,我可以refreshObject:mergeChanges
使用 Department 对象在 Main 上下文上执行。正如预期的那样,这将重新故障部门对象,打破保留周期并在该上下文中取消分配部门和员工实体。
下一步是打破存在于 Root 上下文中的保留循环(保存 Main 上下文已将实体传播到 Root 上下文)。我可以在这里做同样的技巧,并refreshObject:mergeChanges
在带有 Department 对象的 Root 上下文中使用。
奇怪的是:当我的根上下文是用 NSMainQueueConcurrencyType 创建的(所有分配都重新出错并解除分配)时,这工作正常,但是当我的根上下文是用 NSPrivateQueueConcurrencyType 创建时不起作用(所有分配都重新出错,但没有解除分配)。
旁注:根上下文的所有操作都在 performBlock(AndWait) 调用中完成
更新 15/04:第 2 部分
当我使用 NSPrivateQueueConcurrencyType 在根上下文上执行另一个(无用,因为没有更改)保存或回滚时,对象似乎已被释放。我不明白为什么这与 NSMainQueueConcurrencyType 的行为不同。
16/04 更新:演示项目
我创建了一个演示项目:http ://codegazer.com/code/CoreDataTest.zip
21/04 更新:到达那里
谢谢 Jody Hagings 的帮助!
我正在尝试refreshObject:mergeChanges
移出我的 ManagedObjectdidSave
方法。
您能否向我解释一下两者之间的区别:
[rootContext performBlock:^{
[rootContext save:nil];
for (NSManagedObject *mo in rootContext.registeredObjects)
[rootContext refreshObject:mo mergeChanges:NO];
}];
和
[rootContext performBlock:^{
[rootContext save:nil];
[rootContext performBlock:^{
for (NSManagedObject *mo in rootContext.registeredObjects)
[rootContext refreshObject:mo mergeChanges:NO];
}];
}];
顶部的不会释放对象,底部的会。