Core Data (Lightweight Migration)

轻量级迁移

如果只是对模型进行简单的更改(例如像实体添加新属性),则Core Data可以自动执行数据迁移,称为轻量级迁移。轻量级迁移和普通的迁移基本相同,除了提供映射模型之外,Core Data可以从源和目标管理对象模型之前的差异推断出。

轻量级迁移在应用程序开发的早起阶段特别方便,当程序员可能经常更改托管对象模型时,但是又不想重新生成测试数据。那么可以迁移现有的数据,而无需为用于创建需要迁移的存储的每个模型版本创建自定义映射模型。

使用轻量级迁移的另一个优点 - 超出了你不需要自己创建映射模型的事实 - 就是如果使用推断的模型并且使用SQLite存储,则Core Data可以原味执行迁移 通过发出SQL语句。这可以表现出显著的新能优势,因为Core Data不需要加载任何数据。因此,竟可能的鼓励开发人员使用推断迁移,即使是开发人员自己创建的映射模型也是微不足道的。

Core Data 必须能够映射

要执行自动轻量级迁移, Core Data 需要能够在运行的时候查找源和目的托管对象模型。Core Data查找NSBundle的allBundles和allFrameworks方法返回的包中模型。如果将模型储存在其他位置,则必须按照使用迁移管理器中描述的步骤(如果无法自动找到模型)。然后,Core Data必须分析持久性实体和属性的模式更改,并生成推断的映射模型。

对于Core Data能够生成推断的模型映射,更改必须符合明显的迁移模式,例如:

  • 简单的添加新属性
  • 删除属性
  • 非可选属性变可选顺属性
  • 可选属性变非可选属性,并定义默认值
  • 重命名实体或者属性

如果重命名实体或属性,则可以将目标模型中的重命名标识符设置为源模型中相应属性或实体的名称。可以使用Xcode Data Modeling 工具的属性检查器(用于实体或属性)在管理对象模型中设置重命名标识符。例如:

  • 把汽车实体重命名为汽车(Rename a Car entity to Automobile)
  • 重命名汽车的颜色属性为绘制颜色(Rename a Car's color attribute to paintColor)

重命名标识符穿件“规范命名”,因此开发人员应该将重命名标识符设置为源模型中属性的名称(除非该属性已具有重命名标识符)。这意味着开发人员可以重命名模型的版本2中的属性,然后将其他重命名为版本3,重命名将从版本2到版本3或者从版本1到版本3正常工作。

此外Core Data 还支持:

  • 添加关系并改变关系的类型
  • 可以添加新的关系或者删除现有的关系。
  • 重命名关系(通过重命名标识符,就像一属性)。
  • 将关系一对一改变为一对多,或者是一个非有序的关系,以便排序(反之亦然)。
  • 改变实体的层次结构
  • 可以添加、删除、重命名实体
  • 可以创建一个新的父或者子实体,并在实体层次结构上,上下移动属性
  • 可以将实体移出层次结构,但是不能合并实体的层次结构;如果两个现有的实体不在源中共享一个公共父实体,则它们不能在目标中共享一个公共父实体。

使用选项字典请求自动迁移

开发人员可以使用可选字典请求自动迁移,通过addPersistentStoreWithType:configuration:URL:options:error;.通过将与NSMigratePersistentStoresAutomaticallyOption和NSInferMappingModelAutomaticallyOption键对应的值设置为YES:

NSError *error = nil;
NSURL *storeURL = <#The URL of a persistent store#>;
NSPersistentStoreCoordinator *psc = <#The coordinator#>;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
 
BOOL success = [psc addPersistentStoreWithType:<#Store type#>
                    configuration:<#Configuration or nil#> URL:storeURL
                    options:options error:&error];
if (!success) {
    // Handle the error.
}

如果你希望实现确定Core Data是否可以推断源模型和目标模型之前的映射,而无需实际执行迁移工作,则可以使用NSMappingModel的推断方法 - MappingModelForSourceModel:destinationModel:error。如果Core Data能够创建它,则返回推断的模型,否则返回nil。

如果无法自动找到模型,请使用迁移管理器(Migration Manager)

要执行自动迁移,Core Data必须能够在运行的时候找到源和目标托管对象模型本身。如果需要将模型防止在未被自动发现检查的位置,则需要使用迁移管理其(NSMigrationManager的实例)自动生成推断的模型并启动迁移。
一下代码示例说明了如果生成推断的模型,并使用迁移管理器启动迁移。该代码假定开发人员已经实现了两个方法 - sourceModel和destinationModel - 分别返回源和目标托管对象模型。

- (BOOL)migrateStore:(NSURL *)storeURL toVersionTwoStore:(NSURL *)dstStoreURL error:(NSError **)outError {
 
    // Try to get an inferred mapping model.
    NSMappingModel *mappingModel =
        [NSMappingModel inferredMappingModelForSourceModel:[self sourceModel]
                        destinationModel:[self destinationModel] error:outError];
 
    // If Core Data cannot create an inferred mapping model, return NO.
    if (!mappingModel) {
        return NO;
    }
 
    // Create a migration manager to perform the migration.
    NSMigrationManager *manager = [[NSMigrationManager alloc]
        initWithSourceModel:[self sourceModel] destinationModel:[self destinationModel]];
 
    BOOL success = [manager migrateStoreFromURL:storeURL type:NSSQLiteStoreType
        options:nil withMappingModel:mappingModel toDestinationURL:dstStoreURL
        destinationType:NSSQLiteStoreType destinationOptions:nil error:outError];
 
    return success;
}

你可能感兴趣的:(Core Data (Lightweight Migration))