将核心数据属性类型从Integer32更改为String

时间:2014-04-04 18:47:44

标签: ios objective-c core-data migration

我之前处理过轻量级迁移以及映射基本更改,但是我已经用Google搜索并溢出,并且没有找到类似的情况,其中实体名称保持不变,但是属性类型正在从int变为string(我认为这很容易做到)

我认为通过继承NSEntityMigrationPolicy,我在正确的轨道上,然后我将mappingmodel中的自定义策略字段设置为此子类(即使在Xcode重新启动后它也没有自动完成...)

enter image description here

但是我发现createDestinationInstancesForSourceInstance没有被调用 enter image description here

现在,因为我正在处理自定义映射模型和策略,我是否还应该推断映射模型,但是在持久存储中自动关闭迁移?

NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption:@NO,
                          NSInferMappingModelAutomaticallyOption:@YES};

非常感谢任何帮助!

我真的希望在属性映射表达式中能够执行类似$ source.incrementer.string的操作:)

Current Mapping

2 个答案:

答案 0 :(得分:7)

你不能使用轻量级迁移,所以它有点难(感谢Apple),但并非不可能

在Xcode 7.1中一步一步:

<强> 1。创建新的模型版本:

  1. 选择您的.xcdatamodeld型号 - &gt; Editor - &gt; Add model version ...
  2. 编辑新模型的实体attribute type
  3. 当前模型版本更改为新的(文件检查器)。您应该看到绿色刻度标记已移动。
  4. Current model

    <强> 2。自定义核心数据映射模型

    1. New file -> Mapping Model(核心数据 - &gt;映射模型)
    2. 选择source(来自型号)和target(模型)版本的模型
    3. 自定义映射模型包含以这种方式调用的实体映射:NameToName。更改此文件中目标实体中已更改属性的值表达式反映了您需要的值:FUNCTION($entityPolicy, "<*transformingMethodName*>" , $source.<*attributeName*>)
    4. - transformingMethodName:将调用以转换属性类型的自定义方法。 (将在下一步中定义 - 保持)

      - attributeName:您更改的属性名称

      1. 创建<*EntityName*>TransformationPolicy类作为NSEntityMigrationPolicy
      2. 的子类
      3. 实施您在上面定义的transformingMethodName(做你需要的东西来改变属性类型)。确保您已将此方法添加到头文件中
      4. 在映射模型中将此类注册为自定义实体迁移策略 (Model.xcmappingmodel - &gt;文件检查器 - &gt;第三列 - &gt;自定义策略 - &gt;输入名称您的TransformationPolicy类。)
      5. Register migration policy class

答案 1 :(得分:3)

首先,您是否尝试过轻量级迁移,看看它是否能解决这个问题?就SQLite而言,它并不关心你是否正在将int更改为varchar,并且应该能够轻松地完成它。

就映射模型而言,当Core Data找到该迁移的映射模型时,持久性存储中的选项将自动被覆盖。因此,您无需关闭这些选项。

对于重量级迁移,您需要实现几种生命周期方法才能使其正常工作,仅实现-createDestinationInstancesForSourceInstance...可能不足以正确识别和使用该类。我建议使用断点删除所有方法并跟踪哪些方法被调用。我有一段时间没有进行大量迁移,所以我对所需方法的记忆是模糊的。

话虽如此,为此进行大量迁移是解决此问题的一种非常昂贵的方法。虽然它是正确的方式,但实际上并非最佳方式。我会考虑做其他事情(假设轻量级迁移不“只是工作”):

  • 为字符串属性指定一个新名称
    • 在您的子类中创建一个方便覆盖,它提取旧的int并在使用时设置新字符串;或
    • 如果您需要全部,请考虑进行迁移测试以确定是否需要迁移,然后在轻量级迁移(添加新属性)之后遍历实体并手动将int设置为字符串转换。

我建议选择这些选项,因为重量级的迁移非常繁重。它会产生内存问题,特别是如果您的数据存储甚至是远程大的话。它会将数据模型的两个副本加载到内存中以进行迁移。许多iOS应用程序无法处理。它也很慢,可能会导致发射问题。