既然 objectID 在临时对象和永久对象之间发生变化,如何有效地处理 Core Data 中的临时对象?

Posted

技术标签:

【中文标题】既然 objectID 在临时对象和永久对象之间发生变化,如何有效地处理 Core Data 中的临时对象?【英文标题】:How does one effectively handle temporary objects in Core Data since the objectID changes between temporary objects and permanent objects? 【发布时间】:2011-04-07 16:50:18 【问题描述】:

在 Core Data 中处理临时对象的最佳方式是什么?我已经看到了创建临时上下文、将它们插入到 nil 上下文中等的解决方案。

但是,这是我在这两种解决方案中看到的问题。我将 Core Data 用于我的对象模型,并且在我的一些视图中存储了一个 NSSet 的 Core Data 对象。我遇到的问题是,当存储对象时,objectID 发生了变化,这实际上使存储在任何 NSSet 中的任何内容都无效,因为 isEqual 和 hash 现在不同了。虽然我可以使存储在 NSSet 中的对象失效,但这通常并不实用,而且肯定并不总是那么容易。

以下是我考虑过的事情:

1) 覆盖 NSManagedObject 上的 isEqual 方法和哈希(显然不好)

2) 不要在 NSSet 中放置任何 NSManagedObject(使用密钥始终固定的 NSDictionary)

3) 使用完全不同的类型存储在 NSSet 中,我可以在其中正确实现 isEqual 和哈希码方法

有人对此有更好的解决方案吗?

【问题讨论】:

【参考方案1】:

NSSet 中的ManagedObjects ——这听起来像是核心数据关系。为什么不简单地将您的临时 managedObjects 存储在一个关系中,并让 Core Data 处理您现在遇到的问题。然后您可以专注于何时以及如何删除临时对象,或中断关系或任何需要的东西。

【讨论】:

【参考方案2】:

但是,这是我在这两种解决方案中看到的问题。我将 Core Data 用于我的对象模型,并且在我的一些视图中存储了一个 NSSet 的 Core Data 对象。我遇到的问题是,当存储对象时,objectID 发生了变化,这实际上使存储在任何 NSSet 中的任何内容都无效,因为 isEqual 和 hash 现在不同了。

tjg184,

您的问题不是过渡到永久 ID,而是您的容器类依赖于不可变哈希。因此,将您的容器类更改为数组或字典,这个问题就会消失。 (您放弃使用数组进行唯一化,但通过瞬态集执行唯一化很容易处理。)

安德鲁

【讨论】:

【参考方案3】:

一种可能的解决方案是使用 [NSManagedObjectContext obtainPermanentIDsForObjects:error:] 将临时 ID 转换为永久 ID。

但请注意,这可能会很昂贵,特别是如果您有很多需要以这种方式处理的对象。

【讨论】:

【参考方案4】:

您可以继承 NSManagedObject 并覆盖 willSave 和 didSave 方法以删除然后将您的对象重新添加到您的集合中。

我实际上最终使用了一种不同的方法,即使用 NIL 上下文并提供一个基类来处理插入到上下文中。它工作得非常好,是我找到的最干净的解决方案。代码可以在这里找到...Temporary Core Data

【讨论】:

这在某些情况下可能有效,但问题是实际的 NSSet 都在一个单独的视图中。托管对象没有对这些集合的引用。不过,谢谢。

以上是关于既然 objectID 在临时对象和永久对象之间发生变化,如何有效地处理 Core Data 中的临时对象?的主要内容,如果未能解决你的问题,请参考以下文章

6.2临时表--Oracle模式对象

为啥我们在 NSManagedObject 中需要临时 ID

Android Intent传递对象为什么要序列化?

跨线程传递临时 NSManagedObject

-objectRegisteredForID:和--existingObjectWithID之间有什么区别:错误:?

如何通过匹配 ObjectId 字段从嵌套数组中删除对象