为什么在将 Core Data 与 CloudKit 一起使用时关系必须是可选的?

ray*_*ayx 12 core-data ios cloudkit

以下是 Apple文档中将 Core Data 与 Cloudkit 结合使用的要求之一:

所有关系都必须是可选的。由于操作大小限制,关系更改可能无法自动保存。

尝试使用与 CloudKit 的可选关系会导致错误:

线程 1:致命错误:未解决的错误错误域 = NSCocoaErrorDomain 代码 = 134060“发生核心数据错误。” UserInfo={NSLocalizedFailureReason=CloudKit 集成要求所有关系都是可选的,以下不是:Some_Managed_Object: some_attribute}, ["NSLocalizedFailureReason": CloudKit 集成要求所有关系都是可选的,以下不是:Some_Managed_Object: some_attribute]

我想,这不是完全违背了利用关系的目的吗?

例如,假设我有两个实体:AccountTransfer。由于转账始终与源账户和目标账户相关联,Transfer因此应与 具有两个非可选关系Account。但由于上述要求,这些关系必须是可选的

该文档给出了解释:“(这是因为)关系更改可能无法自动保存”。这似乎表明,在Cloudkit和Core Data之间的同步过程中,关系可能不完整,并且不完整的关系暴露给App代码。这对我来说似乎是一个严重的问题,因为:

  1. 在我上面的例子中,这两种关系本质上是非可选的。将它们更改为可选会使模式变得毫无意义。

  2. 即使在那些关系应该是可选的示例中,虽然不完整的关系在语法上是正确的,但它可能会导致意外的不一致问题。

所以我想知道这在真实的应用程序中应该如何工作?对我来说这似乎很破碎。我误解了什么吗?难道使用Cloudkit同步核心数据只适用于一小部分只使用可选关系的应用程序吗?(如果是这样,我想知道其他 Core Data 应用程序如何在设备之间同步数据。)


相关说明:像许多其他人一样,我努力搜索有关 Cloudkit 和 Core Data 使用的同步和冲突解决算法的详细信息。我能找到的仅有的一些信息是:

在最终一致的分布式系统中,您永远无法“知道”云中是否有现有数据或设备。您的应用程序将简单地“在某个时刻发现”该数据存在并且需要设计来处理该数据

是的,Core Data CloudKit 使用 CRDT 实现多对多关系!

NSPersistentCloudKitContainer 使用最后写入者获胜合并策略自动实现冲突解决。

虽然我大致了解这些信息的每一条,但它们并没有给出关于以下问题的直接结论:1)数据更改是否以原子方式在 Cloudkit 和 Core Data 之间同步?更重要的是 2) 同步期间是否会将不完整的数据暴露给应用程序代码?

我的猜测是 1) 否,2) 是。但是,如果在同步期间将不完整的数据更改暴露给应用程序代码,我很难理解如何编写真正的应用程序。难道要使用 Cloudkit 同步核心数据,模式必须设计得能够在不完整的关系下正常工作吗?

如果有人能分享您的理解方式,我将不胜感激。

ray*_*ayx 0

我越想越相信:

  1. 数据更改以非原子方式在 Cloudkit 和 Core Data 之间同步。

  2. 数据同步过程中的不完整状态会暴露给App代码。

  3. 这些行为是由于同步的执行方式造成的,并且很难解决。

因此,Cloudkit 对 Core Data 的内置同步支持仅对一小组不需要数据完整性的简单应用程序有用。

对于严肃的应用程序,需要考虑直接使用 Cloudkit 来实现自定义方法。但编写自己的同步算法并不是一件容易的事,而且充满了陷阱。