5

ALM 很棒。但是我不能让它在一个使用核心数据和 NSDocument 的项目上工作。似乎默认情况下禁用了 ALM。

美好的。对于任何正常的项目,您将在此行的字典中添加两个适当的选项:

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error])

...但是当将 CD 与 NSD 一起使用时,该行不存在(NSPersistentDocument 隐藏了详细信息,我看不到如何修改它们)。

以下方法似乎提供了希望:

configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:

...邮件列表中的一些人(从 4 年前开始)报告成功地覆盖了该方法,更改了选项字典,然后在“super”上重新调用它。可悲的是,这对我不起作用。如果您有类似的问题,我建议您先尝试一下 - 如果仍然无法正常工作,请回到这里 :)

4

2 回答 2

8

从头开始制作一个新的 Cored-Data-with-NSDocument 项目,我尝试了最初不起作用的方法,这次效果很好:

-(BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError **)error
{
    NSMutableDictionary *newOptions = [NSMutableDictionary dictionaryWithDictionary:storeOptions];
    [newOptions setValue:@"YES" forKey:NSMigratePersistentStoresAutomaticallyOption];
    [newOptions setValue:@"TRUE" forKey:NSInferMappingModelAutomaticallyOption];

    return [super configurePersistentStoreCoordinatorForURL:url ofType:fileType modelConfiguration:configuration storeOptions:newOptions error:error];
}
于 2011-06-06T21:02:29.197 回答
1

注意:我怀疑我的问题的根本原因是 Xcode4错误地更新了它使用的私有哈希而不是版本号来跟踪数据模型版本。可能我不小心添加了一些东西,然后删除了它,它改变了哈希值——我原来的模型非常简单,很容易用肉眼比较,没有任何区别。

此外,更一般地说,问题在于 Xcode4仍然无法正确处理 CoreData 项目 - 它默认创建 CoreData 模型作为“版本化”(Xcode3 的重大改进,它注定总是创建无用的模型),但它仍然没有t 对模型中的更改进行任何处理 - 您必须在保存任何更改之前手动记住更新版本(否则您的所有项目迁移将永远失败,没有出路)。

此外,一旦出现问题,我找不到任何“正确”的解决方案——Apple 的核心数据库中缺失的部分太多了。基本上:据我所知, NSPersistentDocument 不完整,不受支持。


最后,我采用了以下 BRUTAL 解决方法:指示使用旧版本的每个人手动编辑 CoreData 存储以声称他们正在运行当前版本。

这 100% 有效,因为与 CoreData 不同,我的应用程序被编写为在导入时智能地纠正任何明显丢失的数据。这很简单,但 CoreData 不允许你说“是的,我已经完成了。没关系。继续打开文件!”

  1. 在旧版本中:“另存为 XML”
  2. 给他们新的标题以复制/粘贴到文件顶部。注意:Apple 使用哈希而不是版本号,这使得这看起来很可怕,即使它不是。我不明白为什么 Apple 会忽略他们自己的版本系统而使用哈希值?
  3. 在新版本中:打开更新的文件
  4. 在新版本中:“保存”

...而且因为我重写了 NSManagedObject 方法:

-wakeFromInsert

并修复任何不正确/丢失的数据,上面的步骤 3 和 4“自动”更新数据。

我知道“正确”的方法是创建一个映射模型,但在大多数情况下它是巨大的矫枉过正......而且Apple首先拒绝加载旧数据。所以,Core Data 甚至拒绝让我更正数据——尽管我的代码很乐意这样做。

(所有旧项目都已正确导入和导出 - 没问题)

恕我直言:CoreData 确实需要对 Apple 进行一些重新设计,以解决他们第一次没有考虑到的所有边缘情况。


注意:快速警告:确保不要更改 awakeFromFetch 中的任何 CoreData 变量 - Apple 在调用该方法之前暂时禁用更改跟踪(这有点可笑 - 它使该方法与所有其他“awakeFrom*”的行为不兼容方法)。

Apple 的建议:在 awakeFromFetch 中,决定要更改的内容,然后将其打包并使用如下内容:

[self performSelector:@selector(myAwakeFromFetchFixItemX:) withObject:X afterDelay:0.01];

...只是想我会为尝试此操作的任何人添加该内容-否则您的导入将正常工作,但您的导出将默默地无法包含固定数据!

于 2011-05-30T14:10:48.013 回答