既然 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 中的临时对象?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我们在 NSManagedObject 中需要临时 ID