在 Core Data 中执行子获取时,在父上下文中修改托管对象是不是会向下传播到子上下文?
Posted
技术标签:
【中文标题】在 Core Data 中执行子获取时,在父上下文中修改托管对象是不是会向下传播到子上下文?【英文标题】:Does modifying a managed object in a parent context propagate down to child contexts when performing a child fetch in Core Data?在 Core Data 中执行子获取时,在父上下文中修改托管对象是否会向下传播到子上下文? 【发布时间】:2014-08-07 01:15:25 【问题描述】:我在 Core Data 的子父上下文中设置了 2 个 NSManagedContext。
_mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_mainContext setParentContext:_parentContext];
[_mainContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
_importContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_importContext setParentContext:_mainContext];
[_importContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
如果我按顺序执行以下命令会发生什么(“fetch”表示 NSFetchRequest):
-
在 mainContext 中获取托管对象 A。
在 importContext 中获取托管对象 A。
在 mainContext 中更新对象 A。
在 importContext 中获取托管对象 A。
importContext (child) -> mainContext (parent) -> Persist Store Coordinator
我的问题是,在第 4 步中,在 importContext 中获取的对象是否具有我在第 3 步中在 mainContext 中所做的更新更改?阅读网络上的文章似乎表明,如果子上下文已经获取数据(因为缓存了上下文?),则在 parentContext 中所做的更改不会传播到子上下文。
【问题讨论】:
【参考方案1】:子上下文的更改会在保存子节点时传播给父节点,而不是在获取期间。变化不会朝另一个方向发展。
在你的场景中...
在 mainContext 中获取托管对象 A。
mainContext 将针对其NSPersistentStoreCoordinator
执行提取请求。协调器将找到应该为请求提供服务的存储并为其提供获取。持久存储将返回一个结果,并根据存储保留行数据的内存副本。 mainContext 现在将拥有该对象的内存副本(但不一定是它的任何属性值)。
在 importContext 中获取托管对象 A。
importContext 没有对该对象的内存引用,因此它会将 fetch 传递给它的父对象 mainContext。 mainContext 会将引用传回它的内存对象 A。如果 mainContext 之前没有获取该对象,或者如果它变成了一个错误,mainContext 会一直获取到持久存储。 Fetches 和 objectWithID:
只进行所需的级别。
在 mainContext 中更新对象 A。
mainContext中的内存对象A发生了变化。
在 importContext 中获取托管对象 A。
返回importContext中的内存对象A。在 mainContext 中所做的更改不会出现在此对象中。
请务必记住,创建上下文时,它是其父级状态的“快照”。除非子项以某种方式无效(即故障或丢弃),否则对父项的后续更改将不会在子项中可见。
You can see how changes propogate in this animation.
【讨论】:
我刚刚偶然发现了这个问题。似乎很奇怪,更改不能从父级传播到子级(例如,使用 mergeChangesFromContextDidSaveNotification:)。我目前正在尝试重置:每当父级保存时,然后通知所有对子级感兴趣的视图重新获取和更新。在我看来,当来自其他线程的更改来自持久存储(或 mergeChangesFromContextDidSaveNotification:) 时,从父级到子级的传播是必要的。【参考方案2】:“获取”是什么意思?获取的结果控制器?
从我的角度来看,您的问题的答案是一般的“是”。假设某种共享父上下文,两个上下文将获取最新的对象,如果一个上下文保存了一个修改过的对象,而另一个上下文做了一些事情来再次加载它,例如,使用 objectID 和 - objectWithID:
在另一个上下文,重新加载它。
【讨论】:
就“获取”而言,我的意思是使用 NSFetchRequest 对象再次查找获取对象。 NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"ManagedItem" inManagedObjectContext:context];以上是关于在 Core Data 中执行子获取时,在父上下文中修改托管对象是不是会向下传播到子上下文?的主要内容,如果未能解决你的问题,请参考以下文章