Core Data 模型版本升级和数据迁移(四)迁移过程

数据迁移过程中,Core Data 创建了两个栈(stacks),一个用于源存储(source store),一个用于目标存储(destination store)。随后,Core Data 从源栈中获取对象,对应的将其插入目标栈。注意:在新栈中,诸多对象是 Core Data 重新创建(re-create)的。

概述


在ios中物理存储是绑定到对应的模型上的,因此,当模型与存储不对应时,就需要迁移。迁移过程有两个时间点供我们采取行动(There are two areas where you get default functionality and hooks for customizing the default behavior):

  • 当检测版本变化(version skew)和初始化迁移过程时;

  • 当执行迁移过程时;

成功执行迁移过程需要两个栈,都由 Core Data 自动为我们创建,一个是面向源存储的栈,一个是面向目标存储的栈,整个栈对栈的拷贝过程分3步完成。

迁移过程必要条件


持久存储的迁移由 NSMigrationManager 的实例完成,为完成迁移,迁移管理器(migration manager)需要涉及很多东西:

  • 目标存储的管理对象模型(The managed object model for the destination store)

    这是持久存储协调器模型(This is the persistent store coordinator’s model)

  • 能打开现有存储的管理对象模型

  • 最重要的,映射模型,定义了如何转换

    如果你使用轻量级迁移,是不需要映射模型的,参见 “Lightweight Migration.”

另外,我们可以定制实体/表迁移策略,如图 Figure 4-1,下图:



定制实体/表迁移策略


如果只是增加几个属性/字段,那就没有必要定制策略;所以,在复杂的情况下,才需要创建 NSEntityMigrationPolicy 的子类,定制迁移策略,比如:

  • 有一个 Person 实体/表,里面存有地址信息(address),现在想把地址信息分离出来成为独立的 Address 实体/表,同时要保证 Address 实体/表中的地址都不重复(ensure uniqueness)。

  • 将某个属性/字段由字符串型(string)转为二进制存储(binary representation)。

定制迁移策略时,即要以子类方式重写 NSEntityMigrationPolicy 的方法,参见下面“迁移三阶段”。

迁移三阶段(Three-Stage Migration)


迁移过程在三个阶段内完成,The migration process itself is in three stages. It uses a copy of the source and destination models in which the validation rules are disabled and the class of all entities is changed to NSManagedObject.

为完成迁移,Core Data 建立sets up two stacks, one for the source store and one for the destination store. Core Data then processes each entity mapping in the mapping model in turn. It fetches objects of the current entity into the source stack, creates the corresponding objects in the destination stack, then recreates relationships between destination objects in a second stage, before finally applying validation constraints in the final stage.

Before a cycle starts, the entity migration policy responsible for the current entity is sent a beginEntityMapping:manager:error:message. You can override this method to perform any initialization the policy requires. The process then proceeds as follows:

  1. Create destination instances based on source instances.

    At the beginning of this phase, the entity migration policy is sent acreateDestinationInstancesForSourceInstance:entityMapping:manager:error: message; at the end it is sent aendInstanceCreationForEntityMapping:manager:error: message.

    In this stage, only attributes (not relationships) are set in the destination objects.

    Instances of the source entity are fetched. For each instance, appropriate instances of the destination entity are created (typically there is only one) and their attributes populated (for trivial cases, name = $source.name). A record is kept of the instances per entity mapping since this may be useful in the second stage.

  2. Recreate relationships.

    At the beginning of this phase, the entity migration policy is sent acreateRelationshipsForDestinationInstance:entityMapping:manager:error: message; at the end it is sent aendRelationshipCreationForEntityMapping:manager:error: message.

    For each entity mapping (in order), for each destination instance created in the first step any relationships are recreated.

  3. Validate and save.

    In this phase, the entity migration policy is sent a performCustomValidationForEntityMapping:manager:error: message.

    Validation rules in the destination model are applied to ensure data integrity and consistency, and then the store is saved.

At the end of the cycle, the entity migration policy is sent an endEntityMapping:manager:error: message. You can override this method to perform any clean-up the policy needs to do.

Note that Core Data cannot simply fetch objects into the source stack and insert them into the destination stack, the objects must be re-created in the new stack. Core Data maintains “association tables” which tell it which object in the destination store is the migrated version of which object in the source store, and vice-versa. Moreover, because it doesn't have a means to flush the contexts it is working with, you may accumulate many objects in the migration manager as the migration progresses. If this presents a significant memory overhead and hence gives rise to performance problems, you can customize the process as described in “Multiple Passes—Dealing With Large Datasets.”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值