17

如何更新子托管对象上下文,使其与父对象具有相同的数据?

据我所知,储蓄时,孩子只走一步,即向父母。然而,当获取 fetch 时,总是会一直深入到父存储和持久存储。所以我希望事情会是一样的。

然而事实并非如此。

我有一个托管对象上下文,它是所有其他托管对象上下文的父级。

一个孩子更改数据并保存。父母也变了。我在父级上执行了 FetchRequest,我看到数据发生了变化。

但是,有些父母的孩子仍然使用旧数据。相同的对象 id 相同的数据。不知何故,财产的价值保持不变。

如何告诉孩子从父母那里重新加载新数据?

更准确地说

说 P 是父母

说它有 C1 C2 C3 作为孩子

然后 C1 更改数据并提交。更改会传播到 P。但是,在 C2 和 C3 执行 executeFetchRequest 仍会显示旧数据。

是什么赋予了?

例如,当我检查 imageBlob 属性时,我得到的是:

孩子:

2013-02-05 13:57:42.865 BadgerNew[78801:c07] imageBlob: <UIImage: 0x89c3c50>
2013-02-05 13:57:42.866 BadgerNew[78801:c07] imageBlob: <null>
2013-02-05 13:57:42.866 BadgerNew[78801:c07] imageBlob: <null>
2013-02-05 13:57:42.866 BadgerNew[78801:c07] imageBlob: <null>

家长:

2013-02-05 13:57:42.868 BadgerNew[78801:c07] imageBlob: <UIImage: 0x114af650>
2013-02-05 13:57:42.868 BadgerNew[78801:c07] imageBlob: <UIImage: 0x8e492e0>
2013-02-05 13:57:42.868 BadgerNew[78801:c07] imageBlob: <UIImage: 0x114c79b0>
2013-02-05 13:57:42.869 BadgerNew[78801:c07] imageBlob: <UIImage: 0xa8c76e0>

这是一个更全面的版本,为什么我记下 moc、父 moc、blob、URL 和对象 ID。孩子:

特别是我希望主队列 managedobject 上下文是父级的另一个子级,而不是所有其他 managedObjectContext 的父级。另一方面,我还希望 mainQueue 托管对象上下文具有最新信息。我想知道标准解决方案是什么。

4

2 回答 2

21

孩子有无效的现有参考。如果您希望在父保存后兄弟姐妹同步,您必须使用reset.

调用之后reset,所有接收者的托管对象都被“遗忘”。如果使用此方法,则应确保还丢弃对使用接收器获取的任何托管对象的引用,因为之后它们将无效。

如果您想更好地控制子上下文中更改的对象,您还可以refreshObject:mergeChanges:在保存父上下文时使用在所有子上下文中更改的单个对象。

于 2013-02-08T06:20:54.110 回答
0

实际上有很多关于如何正确执行此操作的文档,包括 2011 年和 2012 年的 WWDC 会议视频。2012 年会议 214 “核心数据最佳实践”对您来说特别有趣。

例如,对于您的保存,它应该如下所示:

 [child performBlock:^{
     [child save:&error];
     [parent performBlock:^{
         [parent save:&parentError];
     }];
 }];

这样可以保存孩子,更改会转到父级,而您保存在父级上 - 这会将所有这些更改正确传播到其他子上下文。查看您的问题,我认为您的实施可能会遇到其他一些问题,而 Session 214 可能对解决这些问题非常有帮助。

至于重置上下文,我不建议在使用父子上下文时这样做。我也会避免使用refreshObject:mergeChanges:. 为此目的使用 objectWithID 可能会为您节省很多痛苦,因为它将充分利用托管对象上下文的行缓存。它也只会遍历孩子和父母的堆栈以满足请求。

于 2013-02-12T20:08:05.353 回答