Core Data Model Versioning and Data Migration

Core Data 支持随着app开发演进而带来的对象模型(managed object model)升级或修改的管理。

你只能使用创建CoreDataStore的managed object model打开CoreDataStore。改变model会使它和它以前生成的store不兼容。如果你要改变你的模型,你就必须要改变现有存储中的数据-也就是数据存储格式(store format-这被称为迁移(migration)。

要想迁移数据,你既需要创建store的model版本,也需要你想迁移到得model的版本。因此,需要创建带版本的模型(versioned model),带版本的模型(像版本仓库)可以存储下多个版本的model,从中你标记一个为当前版本。Core Data可以使用当前新版本打开以前版本创建的数据存储,并将其迁移至当前版本规范中。因此,为了帮助 Core Data 迁移,需要我们提供新旧版本间的映射信息(map),映射信息有两种方式表示,一是根据带版本的model自身,二是创建独立的映射模型文件(separate mapping model file)。


通常程序版本改变,会涉及到很多方面,Core Data 没有能力为我们自动处理,但提供了一些技术为我们所用:

  • 模型版本管理,允许你指定和区分不同的配置。
    对于版本,有两个观点,程序员观点;从 Core Data观点,具体看 “Understanding Versions.”
    带版本对象模型文件的格式和如何添加版本,参见 “Model File Format and Versions.”
  • CoreData需要知道怎样从原来的model的实体和属性,映射到目标model的实体和属性。映射方式选择(表和字段/实体和属性)
    简单情况下,Core Data 可以推测出(infer)如何映射,具体见轻量级数据迁移” “Lightweight Migration.”
    如果复杂了,Core Data 无法推测,我们必须创建映射模型(mapping model),通过映射模型,表述如何转换(从旧版本到新版本),创建方法见  “Mapping Overview.”
  • 数据迁移的过程参见 “The Migration Process.”,如何执行具体的迁移参见 “Initiating the Migration Process.”
    可以定制迁移过程,如决定是否有必要进行迁移(if-else)、如何找到正确的源模型和目标模型(correct source and destination models)及正确的映射模型来初始化迁移管理器。你只自定迁移过程,比如,在主文件夹(main bundle)之外的位置搜索,或者,利用多个映射模型执行几个阶段的迁移,也可能在大数据集基础上处理。自定迁移过程参见  “Customizing the Migration Process.”
  • 使用了 iCloudApp,只能执行轻量级迁移,具体参  “Migration and iCloud.”


版本的理解

有两个不同的观点:开发者观点和CoreData的观点,这两个不一定总是相同。

开发者的观点通常认为版本标示符代表一个版本,为了支持这一观点,managed object model 有一套标示符—一个model对应一个字符串。

标示符的解释取决于你自己,是否表示程序的版本号、之前提交的版本或者最后提交版本。//这句啥意思,我也不知道

CoreData 只把这些标示符当做简单的暗示。想知道为什么,回想一下持久存储的格式取决于创建它的model,打开持久存储你必须有一个与它向兼容的model。

想象一下,如果改变了model而不改变标示符将会发生什么呢?对于CoreData来说,结构的变化是最重要的,与标示符改变不改变无关。

CoreData对于版本的观点是:它只关心影响存储的model特性。意味着两种model是兼容的:

1.每一个实体如下属性必须相同:name, parent, isAbstract, and properties.className, userInfo,和生效的predicates




2.每一个实体的每一个property,下列属性必须相同:nameisOptional,isTransient, isReadOnly,attributeType

relationships destinationEntity,minCount, maxCount, deleteRule, andinverseRelationship.userInfo和生效的predicates



注意:CoreData忽略任何你设置的标示符。


不是通过列举model的所有相关部分,CoreData为用来比较model是否相同的每一个部分创建了一个32位哈希摘要。这些哈希值包含在存取区的元数据中,以便CoreData能快速决定存储格式是否和managed object model相匹配。

可能会出现这种情况,有两个版本的model,CoreData认为是相同的但开发者认为是不同的。 例如:改变用来表现实体的类的名称,改变属性的内部格式如BLOB—这是与CoreData不相关的,但是在数据完整性上确实十分关键的。CoreData允许你设置一个Hash Modifier。(强制让CoreData 认为本来它认为相同的版本为不同的版本)


Model File Format and Versions

一个支持版本的managed object model在文件系统中用.xcdatamodeld文件表示。.xcdatamodeld文件是一个文件包,它把各个版本model分组,每组用独立的一个.xcdatamodel文件表示,还有一个Info.plist文件它包含版本信息。

model编译成运行时格式— .momd扩展名文件包,包含独立的.mom扩展名文件。使用NSManagedObjectModelinitWithContentsOfURL:加载.momd


向model添加版本,从下图开始:Editor > Add Model Version.设置新名称以及选择基于的model。选中.xcdatamodeld

更改当前model。





Lightweight Migration

轻量级数据迁移(下称LM) Core Data自动执行,适用模型简单改变(simple changes),包括:实体/表中增加新属性/字段,LM与普通迁移原理完全一样,只是不需要映射模型(mapping model (参见 “Mapping Overview”)Core Data自行推测(infers)版本间的差异。


LM 适用于APP早期开发,那时总是在改变数据结构,同时没有必要保存一些测试数据。可以迁移数据而不必创建映射model。

另一个好处是,当你使用推测模型(inferred model)和 SQLite存储时,Core Data 可以执行就地(in situ)迁移,仅仅执行 SQL语句。因为没有载入任何数据,所以此时能保证效率。

LM Core Data必须能推测出映射关系

Core Data 需要能够在运行时找到源和目标的映射关系,一般我们将数据模型存放在 bundles文件夹中(使用 NSBundle  allBundles  allFrameworks 方法获得)Core Data可以找到并发现它,如果放在别的地方,需要按照  “Use a Migration Manager if Models Cannot Be Found Automatically .” 中说的做。Core Data随后自动分析现有表和字段的变化,自动产生推测的映射模型(inferred mapping model)。

以下几种情况,Core Data 可以自动推测出:

  • 添加新属性/字段
  • 删除属性/字段
  • 必填属性/字段改为可选属性/字段
  • 可选属性/字段改为必填属性/字段,并设置默认值
  • 重命名实体/表或属性/字段

如果要重命名,需要将新版本中新实体/属性的重命名标识符renaming identifier)的值设置为原来的实体名或属性名。具体方法:Xcode Data Modeling工具->属性查看器(property inspector)。可以想象,这样做以后,如一个属性的名字在三次修改中都变化了,且都标记了重命名标识符,这样不管是从 version 2 version 3 还是从 version 1 version 3 都可以无错误的迁移。

另外,Core Data 还可以自动猜测出:

  • 增加关系(relationship)和改变关系类型(to one /to many)
    • 增加新关系,删除现有关系
    • 重命名关系名称 (同样设置重命名标识符)
    • 改变关系由对一到对多,或者a non-ordered to-many to ordered (反之亦然)
  • 改变实体/表的体系结构
    • 增加、删除、重命名实体/
    • 增加新的父、子实体/表,移动属性/字段的顺序
    • 将实体/表移出体系
      注意,不能整合(merge)两个实体体系,如果源model两个实体没有共享一个parent,那么在目标model中他们也不能共享一个parent。(if two existing entities do not share a common parent in the source, they cannot share a common parent in the destination

使用选项字典(Options Dictionary)请求自动迁移(Automatic Migration)

你请求自动LM通过调用 addPersistentStoreWithType:configuration:URL:options:error:

定义选项字典,将 NSMigratePersistentStoresAutomaticallyOption  NSInferMappingModelAutomaticallyOption 两个键值设置为YES

01

NSError *error = nil;

02

NSURL *storeURL = <#The URL of a persistent store#>;

03

NSPersistentStoreCoordinator *psc = <#The coordinator#>;

04

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:

05

    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,

06

    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

07

  

08

BOOL success = [psc addPersistentStoreWithType:<#Store type#>

09

                    configuration:<#Configuration or nil#> URL:storeURL

10

                    options:options error:&error];

11

if (!success) {

12

    // Handle the error.

13

}

如果你想决定是否CoreData能推断出mapping model。

可以使用 NSMappingModel  inferredMappingModelForSourceModel:destinationModel:error: 方法,获取推测的映射模型,如果可以推测出返回inferred model,如果不可以,返回 nil


如果不能自动找到模型,则使用迁移管理器(Migration Manager


执行自动迁移,必须保证 Core Data 能够在运行时找到源对象模型和目标对象模型,如果你需要将模型存放于自动搜索范围之外,那么需要我们自己生成推测的模型,并实例化迁移管理器(NSMigrationManager)。如下面的代码,这些代码假设已经实现了sourceModel  destinationModel,这两个方法分别返回源对象和目标对象。


01

- (BOOL)migrateStore:(NSURL *)storeURL toVersionTwoStore:(NSURL *)dstStoreURL error:(NSError **)outError {

02

  

03

    // Try to get an inferred mapping model.

04

    NSMappingModel *mappingModel =

05

        [NSMappingModel inferredMappingModelForSourceModel:[self sourceModel]

06

                        destinationModel:[self destinationModel] error:outError];

07

  

08

    // If Core Data cannot create an inferred mapping model, return NO.

09

    if (!mappingModel) {

10

        return NO;

11

    }

12

  

13

    // Create a migration manager to perform the migration.

14

    NSMigrationManager *manager = [[NSMigrationManager alloc]

15

        initWithSourceModel:[self sourceModel] destinationModel:[self destinationModel]];

16

  

17

    BOOL success = [manager migrateStoreFromURL:storeURL type:NSSQLiteStoreType

18

        options:nil withMappingModel:mappingModel toDestinationURL:dstStoreURL

19

        destinationType:NSSQLiteStoreType destinationOptions:nil error:outError];

20

  

21

    return success;

22

}

Mapping Overview

大多数情况下,CoreData能推测出怎么迁移数据。如果不能,你需要定义怎么转化,这就是这章的内容。

mapping model 是指定从一个版本转换到另一个版本所需要的对象的集合。通常通过Xcode创建mapping model。

像管理对象模型(managed object model),映射模型也是一个对象的集合,,两者并列关系,映射相关的类包括 NSMappingModelNSEntityMappingNSPropertyMapping 

  • 实体/表映射类(NSEntityMapping)的实例指定了源实体(source entity)、对应的目标实体(destination entity)、映射类型(mapping type),映射类型包括:添加 (add)、删除(remove)、拷贝(copy)、转换(transform)。
  • 属性/字段映射类(NSPropertyMapping)的实例指定了属性/字段名称(既有源实体/表中的,也有目标实体/表中的)、值表达式(value expression),该值表达式用于解释如何创建目标实体/表中的属性/字段值。

映射模型不含任何实体/表迁移策略(NSEntityMigrationPolicy)信息,策略信息可能包含在 NSEntityMapping中。关于实体/表迁移策略参见 “Custom Entity Migration Policies.”

如上,我们可以处理简单的属性/字段迁移,方法是:在Xcode中使用映射模型编辑器配置特定的值表达式,比如:

  • 将数据由一个属性/字段迁移至另一个属性/字段
    例子:源表中有一个字段 amount,现在要重命名为 totalCost,那么就可以给新字段 totalCost  的属性/字段映射输入相应的值表达式  $source.amount
  • 将一个属性/字段的值进行转换
    例子:将字段中原本存储的华氏温度值都转换为摄氏温度值,那就使用值表达式  ($source.temperature - 32.0) / 1.8
  • 将对象由一个关系迁移至另一个关系                   源model关系trades在目标model中命名为transactions 在mapping model中的关系value expression中输入

FUNCTION($manager, "destinationInstancesForEntityMappingNamed:sourceInstances:", "TradeToTrade", 

$source.trades)(这里假设迁移 Trade实例的mapping model 命名为 TradeToTrade)


映射模型中有6个预定义的Key可以在值表达式中引用,如下。


注意:在OC源代码中使用他们,就使用NSXxxKey,在值表达式中就使用 $xxxx



Xcode中创建映射模型


Xcode中,文件菜单(File menu),选择新文件(New File),选择设计(Design),选择映射模型(Mapping Model)。.然后,在工作面板上,选择源模型和目标模型,然后点击完成(Finish),Xcode将创建新的映射模型,该模型包含的默认映射都是 Xcode 根据源模型和目标模型自动推测出来的。例如,Xcode自动根据 Figure 1-1  Figure 1-2 创建了映射模型 Figure 4-1,如下:

 Figure 4-1  Mapping model for versions 1-2 of the Core Recipes models


注意:自定义值表达式中的Xcode保留字(Reserved words: 如果你的值表达式中出现了Xcode保留字,如SIZEFIRST、、LAST,那么你必须转义处理,使用#符号,如:$source.#size


The Migration Process

数据迁移过程中,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 建立两个栈,源存储栈和目标存储栈. 然后处理每个实体映射. 取出当前实体的对象到源存储栈,在目标存储站建立对应的对象。第二阶段,为目标对象创建关系,第三阶段,应用验证限制。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:

循环开始前,为当前实体负责的实体迁移策略 被发送beginEntityMapping:manager:error:你可以重写这个方法执行策略的初始化。

  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.

这个阶段的开始,entity migration policy发送

       createDestinationInstancesForSourceInstance:entityMapping:manager:error:

这个阶段的结尾发送endInstanceCreationForEntityMapping:manager:error: 这个阶段只为目标对象设置属性而不设置关系。

取得源实体的所有实例,对每个实例,创建恰当的目标实体实例和它的属性。保存实体映射,可能会在第二阶段用到它。

  1. 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.

这个阶段的开始entity migration policy发送createRelationshipsForDestinationInstance:entityMapping:manager:error:

这个阶段的结尾 entity migration policy发送endRelationshipCreationForEntityMapping:manager:error: 

  1. 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.”

Initiating the Migration Process

这个章节讲述怎么初始化迁移过程,默认迁移过程怎么工作。

Initiating the Migration Process

初始化 persistent store coordinator时,你指定一个managed object modelcoordinator使用这个model打开persistent store

你通过调用addPersistentStoreWithType:configuration:URL:options:error:打开persistent store 。如何使用这个方法取决于你是否使用 model versioning和怎么使用迁移是否你选择使用默认的迁移过程或者自定义版本变化检测和迁移bootstrapping

下列不同情景及你该做些什么:

· 你的应用程序不支持版本

直接使用addPersistentStoreWithType:configuration:URL:options:error:,如果coordinatormodel和存储结构不匹配。coordinator检测出,并报错。addPersistentStoreWithType:configuration:URL:options:error:返回NO

你的应用程序支持版本变化,并且你选择使用LM或者使用默认的迁移过程。

参照“Lightweight Migration”“The Default Migration Process”

与不支持版本变化的方法的本质区别是你命令coordinator自动迁移存储到当前的版本,通过向options字典添加 key为NSMigratePersistentStoresAutomaticallyOption值为[NSNumber numberWithBool:YES]的条目。

你的应用支持版本变化,并且你使用自定义的版本变化检测和数据变迁方式。

在打开存储之前,使用isConfiguration:compatibleWithStoreMetadata:检查存储结构是否兼容coordinator’s model

如果兼容,你可以直接使用addPersistentStoreWithType:configuration:URL:options:error:打开存储。

如果不兼容,你必须先迁移存储,然后再打开它。

你也可以使用addPersistentStoreWithType:configuration:URL:options:error:检测是否需要数据迁移。但它是个重量级操作,而且效率很低。


两个正交概念?

1. 迁移过程中可以执行自定义编码。

2.版本变化检测和数据变迁自展?可以使用自定义的编码。


迁移策略类允许你自定义以各种方式自定义迁移。你可能使用自定义版本检测和数据迁移,以便你可以控制迁移过程。举个例子:如果你有一个很大的存储,可以为两个model设置迁移管理,然后使用一系列的映射model迁移数据到目标存储区。允许framework限制转化过程内存中的数据量。

The Default Migration Process

打开存储并执行迁移数据,使用类似下面的代码:

NSError *error;


NSPersistentStoreCoordinator *psc = <#The coordinator#>;


NSURL *storeURL = <#The URL of a persistent store#>;


NSDictionary *optionsDictionary =


    [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]


                    forKey:NSMigratePersistentStoresAutomaticallyOption];


 


NSPersistentStore *store = [psc addPersistentStoreWithType:<#Store type#>


                                configuration:<#Configuration or nil#>


                                URL:storeURL


                                options:optionsDictionary


                                error:&error];

如果迁移成功,重命名存储,在 storeURL添加一个“~”后缀。

addPersistentStoreWithType:configuration:URL:options:error:的实现过程中,CoreData做了如下的事情:

1.试图找到一个可以打开存储的managed object model

CoreData遍历程序中的model逐个进行尝试,如果不能找到一个合适的model,CoreData 返回nil和一个error。

2.试图找到一个映射model,从当前存储对应的managed object model(能打开当前存储的model) 到 coordinator指定的model。

CoreData遍历程序中的映射model逐个尝试,如果不能找到适合的映射model,CoreData 返回NO 和一个error。

3.创建一些映射model需要的迁移策略实例


尽管使用了默认的迁移程序,你也可以通过使用自定义的迁移策略类自定义迁移过程


Customizing the Migration Process

只有在你想自己初始化迁移的时候,你自定义一个迁移过程。你可以在main bundle外搜索model,通过使用不同的映射model分几个部分执行迁移来处理大数据量的迁移。

Is Migration Necessary

在初始化迁移过程之前,判断是否需要迁移。

NSPersistentStoreCoordinator *psc = /* get a coordinator */ ;


NSString *sourceStoreType = /* type for the source store, or nil if not known */ ;


NSURL *sourceStoreURL = /* URL for the source store */ ;


NSError *error = nil;


 


NSDictionary *sourceMetadata =


    [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:sourceStoreType


                                  URL:sourceStoreURL


                                  error:&error];


 


if (sourceMetadata == nil) {


    // deal with error


}


 


NSString *configuration = /* name of configuration, or nil */ ;


NSManagedObjectModel *destinationModel = [psc managedObjectModel];


BOOL pscCompatibile = [destinationModel


            isConfiguration:configuration


            compatibleWithStoreMetadata:sourceMetadata];


 


if (pscCompatibile) {


    // no need to migrate


}



Initializing a Migration Manager

使用initWithSourceModel:destinationModel:初始化迁移管理。首先你需要找到一个合适的model(能打开存储的),通过使用NSManagedObjectModel’smergedModelFromBundles:forStoreMetadata:得到这个model,如果得到了合适的model,你就可以使用如下代码创建一个迁移管理了。(接着上面那段代码)

NSArray *bundlesForSourceModel = /* an array of bundles, or nil for the main bundle */ ;


NSManagedObjectModel *sourceModel =


    [NSManagedObjectModel mergedModelFromBundles:bundlesForSourceModel


                            forStoreMetadata:sourceMetadata];


 


if (sourceModel == nil) {


    // deal with error


}


 


MyMigrationManager *migrationManager =


    [[MyMigrationManager alloc]


            initWithSourceModel:sourceModel


            destinationModel:destinationModel];



Performing a Migration

使用NSMigrationManager’s migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destinationOptions:error:执行迁移。

使用这个方法前,你需要整理一些参数。大多是都很简单,唯一需要些工作的是得到合适的映射model(可以使用NSMappingModel’smappingModelFromBundles:forSourceModel:destinationModel:)同样是接着上段代码

NSArray *bundlesForMappingModel = /* an array of bundles, or nil for the main bundle */ ;


NSError *error = nil;


 


NSMappingModel *mappingModel =


    [NSMappingModel


            mappingModelFromBundles:bundlesForMappingModel


            forSourceModel:sourceModel


            destinationModel:destinationModel];


 


if (mappingModel == nil) {


        // deal with the error


}


 


NSDictionary *sourceStoreOptions = /* options for the source store */ ;


NSURL *destinationStoreURL = /* URL for the destination store */ ;


NSString *destinationStoreType = /* type for the destination store */ ;


NSDictionary *destinationStoreOptions = /* options for the destination store */ ;


 


BOOL ok = [migrationManager migrateStoreFromURL:sourceStoreURL


                  type:sourceStoreType


                  options:sourceStoreOptions


                  withMappingModel:mappingModel


                  toDestinationURL:destinationStoreURL


                  destinationType:destinationStoreType


                  destinationOptions:destinationStoreOptions


                  error:&error];



Multiple Passes—Dealing With Large Datasets

上述的基本方法,是迁移管理处理两个model,重复映射model步骤,迁移数据。因为CoreData执行三阶段迁移。先创建所有数据,关联数据到第二个存储,必须维护一个“关联表”(说明目标存储中的哪个对象是源存储的迁移版本)。

映射model作为migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destinationOptions:error:的参数。如果你可以分离部分图?创建他们用分离的映射model,你可以做如下:

1.得到源model和目标model

2.创建迁移管理

3.找到所有映射model,存储在数组中。

4.遍历数组,调用: migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destinationOptions:error: 

这允许你迁移大量数据,而不一次性引进所有数据。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值