注意:我怀疑我的问题的根本原因是 Xcode4错误地更新了它使用的私有哈希而不是版本号来跟踪数据模型版本。可能我不小心添加了一些东西,然后删除了它,它改变了哈希值——我原来的模型非常简单,很容易用肉眼比较,没有任何区别。
此外,更一般地说,问题在于 Xcode4仍然无法正确处理 CoreData 项目 - 它默认创建 CoreData 模型作为“版本化”(Xcode3 的重大改进,它注定总是创建无用的模型),但它仍然没有t 对模型中的更改进行任何处理 - 您必须在保存任何更改之前手动记住更新版本(否则您的所有项目迁移将永远失败,没有出路)。
此外,一旦出现问题,我找不到任何“正确”的解决方案——Apple 的核心数据库中缺失的部分太多了。基本上:据我所知, NSPersistentDocument 不完整,不受支持。
最后,我采用了以下 BRUTAL 解决方法:指示使用旧版本的每个人手动编辑 CoreData 存储以声称他们正在运行当前版本。
这 100% 有效,因为与 CoreData 不同,我的应用程序被编写为在导入时智能地纠正任何明显丢失的数据。这很简单,但 CoreData 不允许你说“是的,我已经完成了。没关系。继续打开文件!”
- 在旧版本中:“另存为 XML”
- 给他们新的标题以复制/粘贴到文件顶部。注意:Apple 使用哈希而不是版本号,这使得这看起来很可怕,即使它不是。我不明白为什么 Apple 会忽略他们自己的版本系统而使用哈希值?
- 在新版本中:打开更新的文件
- 在新版本中:“保存”
...而且因为我重写了 NSManagedObject 方法:
-wakeFromInsert
并修复任何不正确/丢失的数据,上面的步骤 3 和 4“自动”更新数据。
我知道“正确”的方法是创建一个映射模型,但在大多数情况下它是巨大的矫枉过正......而且Apple首先拒绝加载旧数据。所以,Core Data 甚至拒绝让我更正数据——尽管我的代码很乐意这样做。
(所有旧项目都已正确导入和导出 - 没问题)
恕我直言:CoreData 确实需要对 Apple 进行一些重新设计,以解决他们第一次没有考虑到的所有边缘情况。
注意:快速警告:确保不要更改 awakeFromFetch 中的任何 CoreData 变量 - Apple 在调用该方法之前暂时禁用更改跟踪(这有点可笑 - 它使该方法与所有其他“awakeFrom*”的行为不兼容方法)。
Apple 的建议:在 awakeFromFetch 中,决定要更改的内容,然后将其打包并使用如下内容:
[self performSelector:@selector(myAwakeFromFetchFixItemX:) withObject:X afterDelay:0.01];
...只是想我会为尝试此操作的任何人添加该内容-否则您的导入将正常工作,但您的导出将默默地无法包含固定数据!