部门与员工之间存在一对多的关系。
我有以下Managed Object Contexts:
- Root: 连接到持久性存储协调器
- Main: 具有父级Root的上下文
当我想创建一个员工时,我会执行以下操作:
- 我有一个Main上下文中的部门
- 我在Main上下文中创建一个员工
- 我将部门分配给员工的部门属性
- 我保存Main上下文
- 我保存Root上下文
这会在Main上下文和Root上下文中都创建一个保留循环。
如果我没有使用子上下文(全部在Root上下文中完成),那么我可以通过在员工上调用
refreshObject:mergeChanges
来打破保留循环。在我的情况下,使用这种方法可以在Main上下文中打破循环,但是我该如何在Root上下文中打破循环呢?注意:这只是一个简单的例子来描述我的问题。在Instruments中,我可以清楚地看到分配数量增加。在我的应用程序中,我有比一个级别更深的上下文,导致更大的问题,因为我每个保存的上下文都会得到一个新的带有保留周期的实体分配。
更新15/04:NSPrivateQueueConcurrencyType vs NSMainQueueConcurrencyType 在保存了两个上下文之后,我可以对Department对象的主上下文执行
refreshObject:mergeChanges
。这将如预期一样重新加载Department对象,打破保留周期并在该上下文中释放Department和Employee实体。下一步是打破存在于根上下文中的保留周期(保存主上下文已将实体传播到根上下文)。我可以在这里使用相同的技巧,并使用
refreshObject:mergeChanges
在根上下文中与Department对象一起使用。奇怪的是:当我的根上下文创建为NSMainQueueConcurrencyType时(所有分配都被重新加载并释放),这很好用,但是当我的根上下文创建为NSPrivateQueueConcurrencyType时(所有分配都被重新加载,但不是释放)。
Note: 所有Root上下文的操作都在performBlock(AndWait)调用中完成。
更新15/04:第二部分 当我使用NSPrivateQueueConcurrencyType在Root上下文上进行另一个(无用的,因为没有更改)保存或回滚时,对象似乎已被释放。我不明白为什么这与NSMainQueueConcurrencyType的行为不同。
更新16/04:演示项目 我创建了一个演示项目:http://codegazer.com/code/CoreDataTest.zip 更新21/04:接近成功 感谢Jody Hagings的帮助! 我试图将refreshObject:mergeChanges移出我的ManagedObject didSave方法。 您能否向我解释以下两者之间的区别:
[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];
}];
}];
顶部的代码不会释放对象,而底部的代码会释放对象。
performBlock
包装了完整的“用户事件”,但performBlockAndWait
则不是。 - Jody Hagins