Core Data 学习:轻量级版本迁移(Lightweight Migration)

什么时候需要版本迁移呢?

     答案很简单,什么时候改变数据模型,什么时候就需要版本迁移 .
   Core Data 支持对数据模型 (data model) 改变的管理。改变数据模型将造成该数据模型与之前的持久化存储 (stores) 不兼容,而出现错误。所以,如果我们改变了自己的数据模型 ,就需要将原有的持久化存储中的数据转移到新的模型版本,这一过程就称为版本迁移(migration)

为什么需要进行版本迁移?

      当我们发布应用之后,再添加一些新的特性,我们将需要更新持久化存储。在我们开发的过程中,很好操作,删除 APP 重新运行程序即可,但是如果用户下载了我们的 APP ,我们就需要注意了,用户肯定不希望存储的数据消失了。所以我们要进行版本迁移,既要保存原有数据又能够添加新功能。

版本迁移的过程

     当我们初始化堆栈的时候,其中有一步骤是涉及到添加持久化存储( store )到持久化存储协调器( persistent store coordinator )。当进行这一步操作的时候, Core Data 在添加持久化 store 到持久化存储协调器之前做了一些事情:

   首先 Core Data 分析了 store 的模型版本( model version )。接下来, Core Data 将会把这个模型版本跟协调器中 配置的 数据模型( data model )进行比较。如果持久化存储的模型版本 (store’s model version) 和持久化存储协调器的模型版本不匹配,这时候 Core Data 会根据是否被允许,将决定是否执行迁移 (migration) 操作。

      为了进行迁移,我们需要之前的模型版本和当前的模型版本。我们能够创建一个版本模型包含多个数据模型文件,在版本模型中我们需要明确标记哪一个版本为当前使用版本。 Core Data 能够将之前创建的模型版本中的持久化存储,迁移到当前版本。为了帮助 Core Data 实现执行迁移版本,我们必须提供怎样从一个模型版本映射到另一个模型版本的信息。 一旦 Core Data 确定映射模型( mapping model ),迁移过程将开始。

注意:如果版本迁移并不被允许,而且 持久化存储( store ) model 是不相容的, Core Data 将不再把 store 与协调器相关联,而是给定一个合理出错原因 code

迁移发生的三个步骤:
 
 1)首先,Core Data 将复制所有的对象,从一个数据 store 到另外一个数据 store
 2)接下来,Core Data将根据关系映射连接所有相关联的对象。
 3 )在目的模型( destination model )中强制验证任意数据,在数据复制期间将使目的模型验证失效。
 
   但是如果 迁移 这个过程出现了错误,那么原始的数据存储会怎么样呢?除非迁移完成并且无错误,Core Datac才去除原始数据存储, 迁移所有的数据, 否则 原始数据存储并不会发生变化。

Lightweight Migration

      如果我们仅仅是对数据模型进行简单改变 ( 比如:为实体添加新的属性 ) Core Data 将能够自动进行数据迁移,我们称之为轻量级版本迁移 (lightweight migration). 轻量级版本迁移是不需要我们自己提供映射模型, Core Data 将推断原始和目的数据模型之间的差别。

     轻量级版本迁移对于应用早期的使用是非常方便,当我们改变数据模型,但是我们并不想重新生成数据,我们可以移动存在的数据而不需要为模型版本创建自定义映射模型。

     为了执行自动轻量级版本迁移, Core Data 需要在运行时能够找到原始和目的数据模型。 Core Data 将在 NSBundle allBundles allFrameworks 等方法返回的 bundles 中寻找数据模型。如果我们存储我们的数据模型在其它地方,我们需要采取一些步骤:可以看 Use a Migration Manager if Models Cannot Be Found Automatically . Core Data 必须分析模式 (schema), 然后改变持久化实体和属性并生成推测映射模型。

为了Core Data 能够生成推测映射模型,对于数据模型的改变必须符合以下情况,例如:

1
:简单的添加一个新的属性
2
:去除某个属性
3
:非可选属性变成可选属性
4
:可选属性变成非可选属性并定义默认值
5
:重命名实体或者属性

如果我们重命名实体或者属性,我们能够在目的数据模型中设置重命名标识符 (renaming identifier) 来命名源数据相关的视图或者数据。该操作,可以直接在 Xcode Data Modeling tool’s property inspector 中,例如:

1):重命名 Car 实体为 Automobile
2):重命名 Car color 属性为 paintColor

除了上面 5 条之外, Core Data 还支持如下情况:

6
:添加关系和改变关系类型

1
)我们能够添加一个新的关系或者删除存在的关系
2
)重新命名关系 ( 使用重命名标识符跟属性一样 )
3
)改变关系从一对一到一对多,或者从一对多无序到有序,反之同样可以

7
:改变实体的层级关系

1
)我们能够添加,去除,重命名实体
2
)我们能够创建新的父或子实体,而且可以在实体层级中移动属性
3
)我们能够移动实体到层级关系之外,但是我们不能够合并实体层级,如果两个存在的实体在源数据模型中并没有共享父实体,那么在目的数据模型中将不能够共享父实体。

轻量级版本迁移使用步骤:

1: Open your .xcdatamodel file.
2:Select Editor in the top menu.
3:Select Add Model Version.
4:Select main .xcdatamodel file and open the File Inspector (right-hand panel).
5:Change current version to the new model version you just created.
6:Change addPresistentStoreWithType options.


1: 打开 XCODE 中的 Editor menu select Add Model Version 。将弹出添加版本弹框,类似于下图:



命名可以随意,不过最好还是在原有的名称基础上加后缀,类似于:原名称 +v2, v3, v4 等不同版本。这里需要你选择基于的数据模型。 Xcode 将基于该数据模型创建副本。

这一步骤我们将创建第二个版本的数据模型,但是我们仍然需要告诉 Xcode 使用最新的版本作为当前模型。 Inspector pan 文件中后侧,找到选择模型版本选项,改为最新的版本名称。如下图:


一旦我们做出这种改变,关注工程导航部分,将看到 little green check mark icon 已经从之前的数据模型转移到了 V2 数据模型。


Core Data 将加载被标记的版本数据,当创建堆栈的时候。老版本在这里就是支持版本的迁移。

2:在自己的CoreData堆栈中添加相关迁移代码,只需要将下面两个key值设置为true,作为options参数传入Core Data堆栈中,然后作为持久化存储对象的options参数。即:  

 addPersistentStoreWithType(storeType: String, configuration:String?, URL storeURL: NSURL?, options: [NSObject :AnyObject]?) 方法中的options

 
  
    lazy var stack :CoreDataStack= CoreDataStack(modelName:"UnCloudNotesDataModel", storeName:"UnCloudNotes", options: [NSMigratePersistentStoresAutomaticallyOption:true,
       NSInferMappingModelAutomaticallyOption:true])

 参数解释:

    NSMigratePersistentStoresAutomaticallyOption:简单一点理解就是自动尝试进行版本迁移。该值将告诉Core Data (theNSPersistentStoreCoordinator, actually)开始进行迁移,如果持久化存储模型与当前数据模型并不匹配。Core Data将处理所有细节,寻找原模型创建目的存储文件,所有的步骤都在这两者之间进行。即分配资源、在应用bundle中映射模型,并执行迁移。

    NSInferMappingModelAutomaticallyOption:自动创建映射模型。它是lightweight migration所进行的另外一半需要,每次迁移都需要映射模型,这里有一个类比:如果你从一个认识的地方旅游到不认识的地方,你将需要地图告诉你去哪。这里映射模型就是引导。


3:运行程序,现在可以在新的数据模型中添加自己需要的实体和属性等相关内容。

补充一点:

如果我们想确定是否 Core Data 能够在原数据模型和目的数据模型之前推测映射模型,而并没有做一些实际的迁移操作,我们能够 NSMappingModel inferredMappingModelForSourceModel:destinationModel:error: 方法进行推测,如果 Core Data 能够创建映射模型,该方法将返回推测的映射模型,否则为 nil.

为了执行自动迁移, Core Data 必须能够在运行时找到原数据模型和目的数据模型,如果我们需要把模型放在某个位置,但是并不能够自动发现,这时,我们需要自己使用迁移管理者 (migration manager,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;
}

相关推荐文章:



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值