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