【问题标题】:Core Data Versioning manually手动控制核心数据版本
【发布时间】:2011-09-18 19:28:40
【问题描述】:

我开发了一个应用程序,iCollege,现在我想让应用程序变得更好。
在测试时,我想从备份中恢复数据。在启动 iCollege 时,应用程序崩溃,因为 Core Data 无法对其进行版本控制。我现在的问题是是否可以手动对核心数据文件进行版本控制,即遍历现有文件的每个托管对象并将对象适合活动模型版本。

这样的事情可能吗?

编辑:非常感谢您快速而详细的回答。我认为我解释我的问题不是很好。这是我的问题的另一种描述。
我有一个使用 Core Data 创建的文件,其中包含一些实体 CourseTeacher 的对象。我用这个文件替换了我的应用程序的核心数据文件。当应用程序下次启动时,我想调用一个方法,该方法使用 CourseTeacher 的对象读取文件的托管对象并将其转换为实体,例如SubjectProfessor。属性也可以改变。我的问题是我是否可以做到这一点,即我可以自己对核心数据文件进行版本控制吗?
我希望我的问题现在可以检查。 :-)

【问题讨论】:

  • 据我了解,可以手动转换您的数据。你遇到了什么错误?
  • "找不到源存储的模型" - 你知道它是如何工作的吗?会很棒的。
  • 好的,我已经回答了。如果您有更多问题,请随时提问。祝你好运!
  • 您只是想重命名实体吗?如果是这样,this answer 可能会对您有所帮助。

标签: iphone ios xcode core-data versioning


【解决方案1】:

虽然理论上您可以手动迁移数据,但这可能不值得。你想使用automatic lightweight migration

要执行自动轻量级迁移,您需要设置两个数据模型,然后在代码中告诉 Core Data 执行迁移。这意味着您在阅读完本文之前不应修改您的数据模型。如果您有,(自动或手动)恢复您的旧模型。您将需要它来进行迁移。以下是自动轻量级迁移的工作原理:

首先,您需要向数据模型添加模型版本。选择现有模型,然后从Editor 菜单中添加一个版本:

系统将提示您命名数据模型并选择基于哪个现有模型。

现在,继续对新模型进行更改。 完成后,您需要告诉 Core Data 将此新模型用作当前版本。我们还没有完成代码,所以这部分很简单。 (代码也很简单。)在右侧面板中,选择活动模型,如下所示:

确保在左侧导航器中选择了您的模型,否则您可能看不到右侧的选项。你应该得到这样的结果:

(我这里其实用的是版本2而不是版本3,但是思路是一样的。)

现在,您需要快速更改您的代码,以便 Core Data 知道为您进行迁移。

在您的应用委托中的 persistentStoreCoordinator 方法中,更改此行:

if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]){

添加到以下内容(在if 语句之前的行中添加):

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];


if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]){

您实际上已经向 Core Data 传递了一个选项字典,告诉它为您迁移数据存储。 (仔细看前面的代码,通读几遍就明白了。)

编辑:你可能可以做你想做的事。如果我理解正确,您应该创建一个新的模型版本,执行轻量级迁移,然后他们手动进行您想要的更改。我的上述答案仍然有效,只是之后您需要进行一些手动更改。

【讨论】:

  • 我编辑了我的问题,因为您的回答是正确的,是的,但不是我想要的。 :)
  • 干得好。我为教程级别的答案鼓掌。
  • 太棒了!很详细的回答
【解决方案2】:

您可以按如下方式执行此操作。核心数据允许您将多个持久存储添加到NSPersistentStoreCoordinator,因此您需要两个与您的协调器关联的存储。请注意,不能使用两种不同的托管对象模型 (MOM),您的所有商店只能使用一个 MOM。

虽然这看起来相当困难,但它却足够简单,因为 Core Data 也允许使用配置。配置具有名称和关联的一组实体。这些集合可能会重叠——也就是说,一个给定的实体可能会出现在多个配置中。见关联documentation

您现在可以通过在不同的商店中拥有不同的实体来轻松解决您的问题, 创建一个模型,该模型将成为您要进行的所有实体的超集 处理(或至少是联合)并定义您需要作为配置的子集。然后,为每个单独的商店指定相关的配置。

类似的东西(只是一个例子 sn-p):

NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] init];
[coordinator addPersistentStoreWithType:type configuration:@"CourseAndTeacher" URL:aURL options:nil error:NULL];
[coordinator addPersistentStoreWithType:type configuration:@"SubjectAndProfessor" URL:anotherURL options:nil error:NULL];

NSManagedObjectContext *context = [[NSManageObjectContext alloc] init];
[context setPersistentStoreCoordinator:coordinator];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-07
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-17
    相关资源
    最近更新 更多