如何删除子托管对象上下文中的临时对象?

Posted

技术标签:

【中文标题】如何删除子托管对象上下文中的临时对象?【英文标题】:How to delete a temporary object on a child managed object context? 【发布时间】:2014-02-08 19:32:12 【问题描述】:

我有一个 CodeData 模型 [电话]>[转发]。所以 Phone 对象有一个 Forwardings 集,反之亦然。

我有一个电话列表,想将其中一个添加到新的转发中。

ForwardingViewController我做:

// Create a new managed object context; set its parent to the fetched results controller's context.
managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[managedObjectContext setParentContext:[fetchedResultsController managedObjectContext]];
self.forwarding = (ForwardingData*)[NSEntityDescription insertNewObjectForEntityForName:@"Forwarding"

所以这会创建一个子 MOC 和一个现在临时的转发。

然后我将self->forwarding 传递给我的PhonesViewController,它会显示所有电话(在表格中)。这个视图控制器只是导航推送的。

当用户点击表格中的一个电话时,我会这样做:

[self.forwarding addPhonesObject:phone];

addPhonesObject 是 CoreData 生成的访问器。

现在,当用户返回ForwardingViewController 并点击取消按钮(因为他决定他根本不想创建新的转发)时,它被解除,这会清理这个孩子managedObjectContext 和还有self.forwarding

执行上述操作后,我收到一个数据库错误(Cocoa 错误 1550)。当试图理解控制台输出时,我的猜测是转发确实被删除了,但是电话对象(当然仍然存在)现在对这个删除的转发有一个空引用。

我的问题。我应该如何正确处理这种情况:在子 MOC 上创建一个临时对象,将其链接到另一个对象(在父 MOC 上),然后再次删除这个临时对象。

【问题讨论】:

【参考方案1】:

你得到的实际错误是什么?

根据您的描述,我猜您的 PhonesViewController 列出的手机来自不同的 NSManagedObjectContext,而不是您创建 ForwardingData 实体的手机。这违反了与 Core Data 的关系规则。规则很简单,要在两个实体之间创建关系,它们必须都来自同一个 NSManagedObjectContext 实例。

我质疑你为什么在这种情况下创建一个临时的NSManagedObjectContext。由于您保留了 ForwardingData 实体,并且您知道何时被取消,因此在按下取消时删除临时实体而不是站起来另一个 NSManagedObjectContext 似乎更干净。

更新

如果您需要使用孩子(根据您的评论),那么您应该通过依赖注入将PhonesViewController 更改为接受NSManagedObjectContext。然后,您可以向它发送与用于创建新实体的 NSManagedObjectContext 实例相同的实例。有了这个改变,一切都会如你所愿。

【讨论】:

啊,这一定是我的问题:使用两个不同的 MOC。简化并在取消时删除 ForwardingData 对象是个好主意(我从 Apple 文档或示例中得到了这个构造)。 Apple 示例非常适合向您展示您可以做什么,但不太适合向您展示您应该做什么。 在没有子 MOC 的情况下运行良好。非常感谢!但是为什么你认为使用儿童 MOC 不是一个好主意 [这里]?使用一个 MOC 有一个副作用:当新的 Forwarding 视图控制器从下方向上滑动时,Forwardings 表上会出现一个空项;当然是因为新的 Forwarding 是在 viewDidLoad 中创建的。 没有子MOC的另一个问题是数据可能同时更新(从服务器拉取);因为这个,我刚刚看到一个 Cocoa 错误 1560,同时创建一个新的转发。 感谢更新,我已经在考虑通过 MOC 了。

以上是关于如何删除子托管对象上下文中的临时对象?的主要内容,如果未能解决你的问题,请参考以下文章

父/子托管对象上下文究竟是如何工作的?

如何安全地删除未保存的托管对象?

从新的子上下文中删除对象

无法在具有现有ObjectWithID 的子上下文中检索临时对象:错误:

核心数据和托管对象上下文

如何在应用程序退出时正确删除“临时”NSManagedObject