为什么NSManagedObjectID会发生变化?

时间:2013-06-14 02:19:02

标签: ios core-data

我不确定这个问题的格式对这个网站是否有用。

基本上,有没有人知道什么使得Apple在每次将数据保存到持久存储时做出NSManagedObjectID更改的设计决定?

我可能错了,但这个决定对我来说听起来很可疑。 没有明显的优势(它是一个UUID!它 唯一!),但它传递了objectID - 它可以在保存对象的任何时候在你的脚下改变。

对我来说这是一个很大的问题因为我使用了三个MOC系统(背景MOC - > UI MOC - >持久性MOC),对象被插入到背景MOC中并通过保存向上传播。保存是异步的,因为它必须在三个不同的MOC上传播并在创建它们之后返回它们,但在它们保存到持久存储之前是非常痛苦的,因为我不能依赖于传递objectID。

我做的事特别错吗?有没有人知道UUID在没有通知的情况下随时可变的优势是什么?

我最大的问题是为什么提供临时的managedObjectID。它有什么意义吗?只是让人们混淆试图使用它吗?

2 个答案:

答案 0 :(得分:9)

我有点困惑为什么你一直说NSManagedObjectID特别是UUID。 URI表示可能与UUID格式具有相似的外观,但我没有在文档中看到它表示“a NSManagedObjectID是UUID”(正如我将在下面讨论的那样,它更多比起那个来说)。为什么Apple以这种方式设计它超出了StackOverflow的范围,所以希望你的问题真的是“什么是Core Data的设计,我该如何使用它?”

文档所说的内容(在Managed Object IDs and URIs中)是,如果您想要进行此类对象跟踪,则应将自己的UUID添加为属性:

  

您有时可以从创建自己的唯一ID(UUID)属性中受益,该属性可以为新插入的对象定义和设置。这允许您使用谓词有效地定位特定对象(但在保存操作之前,只能在原始上下文中找到新对象。)

可以从不可变数据结构中看到NSManagedObjectID更改的原因。它包含persistentStore属性。在您实际保存对象之前,无法确定这一点(例如,您可以调用assignObject:toPersistentStore:)。同样,不要在其URI表示方面考虑NSManagedObjectID;这只是一种序列化格式。真实ID包括持久性存储,如文档中所示:

  

与数据库中的主键一样,标识符包含准确描述持久存储中的对象所需的信息,但不会公开详细信息。

在插入对象之前,无法最终确定该标识符。

答案 1 :(得分:5)

我绝不是核心数据专家,但我的理解是NSManagedObjectID大多数情况下保证是唯一的。例外情况是:

  • 当您创建新对象但尚未提交时,其ID将是临时的。您可以使用isTemporaryId检查此条件。
  • 当后备存储已发生变异时,即如果您正在使用iCloud并迁移到新版本的数据库。

由于您正在讨论单个生命周期,我假设我们正在考虑第一个选项。如果是这种情况,您应该等待获取ID,直到之后您的更改已传播到持久性存储。我想你可以从同一个对象中获取id,即创建对象,保留指向它的指针,保存上下文,然后从保留的指针中获取该对象的id。警告:我从来没有真正做到这一点,这只是基于我阅读文档的结论。

此外,临时ID应该保留,直到您保存上下文,因此您应该只需要担心这一次 - 在第一次保存新对象的上下文之后。

顺便说一下,在我看来CoreData 必须以这种方式实现。如果他们在实际将id插入持久存储之前试图保证id是唯一的,那么如果两个不同的上下文在提交之前获取相同的id会发生什么?保证唯一性/防止id的竞争条件的唯一方法是在将记录插入数据库时​​找到唯一的id ...否则,CoreData必须以某种方式插入虚拟值每个记录一个上下文插入...