在NSPersistentDocument上启用核心数据的自动轻量级迁移

时间:2011-05-16 00:14:43

标签: macos core-data nsdocument

ALM很棒。但我不能让它在使用Core Data with NSDocument的项目上工作。似乎默认情况下禁用ALM。

精细。对于任何正常项目,您可以在此行中向字典中添加两个适当的选项:

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

...但是当使用带有NSD的CD时,该行不存在(NSPersistentDocument隐藏了详细信息,我看不出如何修改它们。)

以下方法似乎带来了希望:

configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:

...邮件列表中的一些人(从4年前开始)报告成功覆盖该方法,更改选项字典,然后在“超级”上重新调用它。遗憾的是,那对我不起作用。如果你有类似的问题,我会建议首先尝试 - 如果它仍然不起作用,那么回到这里:)

2 个答案:

答案 0 :(得分:7)

从头开始创建一个新的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];
}

答案 1 :(得分:1)

注意:我怀疑我的问题的根本原因是Xcode4 错误地更新它使用的私有哈希而不是版本号来跟踪数据模型版本。可能是我偶然添加了一些东西,然后将其删除了,它改变了哈希 - 我的原始模型非常简单,很容易通过眼睛比较,并没有差异。

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

此外,一旦出现问题,我找不到任何“正确”的解决方案 - 苹果公司的Core Data lib中有太多缺失的部分。基本上:据我所知,NSPersistentDocument不完整,不受支持。


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

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

    旧版本中的
  1. :“另存为XML”
  2. 为他们提供了新标题,以便复制/粘贴到文件顶部。注意:Apple使用哈希而不是版本号,这使得它看起来很可怕,尽管它不是。我不明白为什么Apple会忽略他们自己的版本系统并改为使用哈希?
  3. 在新版本中:打开更新的文件
  4. 在新版本中:“save”
  5. ...因为我正在覆盖NSManagedObject方法:

    -awakeFromInsert

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

    我知道“正确”的方式是创建一个映射模型,但是对于大多数情况来说它是大量的过度杀伤......而Apple首先拒绝加载旧数据。因此,Core Data只是拒绝让我更正数据 - 即使我的代码很乐意这样做。

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

    恕我直言:CoreData确实需要在Apple端进行一些重新设计,以修复他们第一次没想到的所有边缘情况。


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

    Apple的建议:在awakeFromFetch中,决定你要改变什么,然后把它打包并使用这样的东西:

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

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