首页 > 其他 > 详细

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

时间:2016-07-13 17:45:17      阅读:314      评论:0      收藏:0      [点我收藏+]
什么时候需要版本迁移呢?

     答案很简单,什么时候改变数据模型,什么时候就需要版本迁移.
   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将在NSBundleallBundlesallFrameworks等方法返回的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):重命名Carcolor属性为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 menuselect 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能够在原数据模型和目的数据模型之前推测映射模型,而并没有做一些实际的迁移操作,我们能够NSMappingModelinferredMappingModelForSourceModel:destinationModel:error:方法进行推测,如果Core Data能够创建映射模型,该方法将返回推测的映射模型,否则为nil.

为了执行自动迁移,Core Data必须能够在运行时找到原数据模型和目的数据模型,如果我们需要把模型放在某个位置,但是并不能够自动发现,这时,我们需要自己使用迁移管理者(migration manager,NSMigrationManager实例对象)来推测模型并初始化。下面的代码解释了怎样使用迁移管理者来生成推测模型,代码中假定我们已经实现了两个方法sourceModeldestinationModel并且能够返回各自的数据模型。

- (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)

原文:http://blog.csdn.net/longshihua/article/details/51879023

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!