版本遷移的設(shè)置是在創(chuàng)建MOC時(shí)給PSC設(shè)置的,為了使代碼更直觀,下面只給出發(fā)生變化部分的代碼,其他MOC的初始化代碼都不變。
// 設(shè)置版本遷移方案
NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES};
// 創(chuàng)建持久化存儲(chǔ)協(xié)調(diào)器,并將遷移方案的字典當(dāng)做參數(shù)傳入
[coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:dataPath] options:options error:nil];
修改實(shí)體名
假設(shè)需要對(duì)已存在實(shí)體進(jìn)行改名操作,需要將重命名后的實(shí)體Renaming ID,設(shè)置為之前的實(shí)體名。下面是Employee實(shí)體進(jìn)行操作。

修改實(shí)體名
修改后再使用實(shí)體時(shí),應(yīng)該將實(shí)體名設(shè)為最新的實(shí)體名,這里也就是Employee2,而且數(shù)據(jù)庫(kù)中的數(shù)據(jù)也會(huì)遷移到Employee2表中。
Employee2 *emp = [NSEntityDescription insertNewObjectForEntityForName:@"Employee2" inManagedObjectContext:context];
emp.name = @"lxz";
emp.brithday = [NSDate date];
emp.height = @1.9;
[context save:nil];
Mapping Model 遷移方案
輕量級(jí)遷移方案只是針對(duì)增加和改變實(shí)體、屬性這樣的一些簡(jiǎn)單操作,假設(shè)有更復(fù)雜的遷移需求,就應(yīng)該使用Xcode提供的遷移模板(Mapping Model)。通過(guò)Xcode創(chuàng)建一個(gè)后綴為.xcmappingmodel的文件,這個(gè)文件是專(zhuān)門(mén)用來(lái)進(jìn)行數(shù)據(jù)遷移用的,一些變化關(guān)系也會(huì)體現(xiàn)在模板中,看起來(lái)非常直觀。
這里還以上面更改實(shí)體名,并遷移實(shí)體數(shù)據(jù)為例子,將Employee實(shí)體遷移到Employee2中。首先將Employee實(shí)體改名為Employee2,然后創(chuàng)建Mapping Model文件。
Command + N 新建文件 -> 選擇 Mapping Model -> 選擇源文件 Source Model -> 選擇目標(biāo)文件 Target Model -> 命名 Mapping Model 文件名 -> Create 創(chuàng)建完成。

Mapping Model 文件
現(xiàn)在就創(chuàng)建好一個(gè)Mapping Model文件,文件中顯示了實(shí)體、屬性、Relationships,源文件和目標(biāo)文件之間的關(guān)系。實(shí)體命名是EntityToEntity的方式命名的,實(shí)體包含的屬性和關(guān)聯(lián)關(guān)系,都會(huì)被添加到遷移方案中(Entity Mapping,Attribute Mapping,Relationship Mapping)。
在遷移文件的下方是源文件和目標(biāo)文件的關(guān)系。

對(duì)應(yīng)關(guān)系
在上面圖中改名后的Employee2實(shí)體并沒(méi)有遷移關(guān)系,由于是改名后的實(shí)體,系統(tǒng)還不知道實(shí)體應(yīng)該怎樣做遷移。所以選中Mapping Model文件的Employee2 Mappings,可以看到右側(cè)邊欄的Source為invalid value。因?yàn)橐獜腅mployee實(shí)體遷移數(shù)據(jù)過(guò)來(lái),所以將其選擇為Employee,遷移關(guān)系就設(shè)置完成了。
設(shè)置完成后,還應(yīng)該將之前EmployeeToEmployee的Mappings刪除,因?yàn)檫@個(gè)實(shí)體已經(jīng)被Employee2替代,它的Mappings也被Employee2 Mappings所替代,否則會(huì)報(bào)錯(cuò)。

設(shè)置遷移關(guān)系
在實(shí)體的遷移過(guò)程中,還可以通過(guò)設(shè)置Predicate的方式,來(lái)簡(jiǎn)單的控制遷移過(guò)程。例如只需要遷移一部分指定的數(shù)據(jù),就可以通過(guò)Predicate來(lái)指定??梢灾苯釉谟覀?cè)Filter Predicate的位置設(shè)置過(guò)濾條件,格式是$source.height<100,$source代表數(shù)據(jù)源的實(shí)體。

Filter Predicate
更復(fù)雜的遷移需求
如果還存在更復(fù)雜的遷移需求,而且上面的遷移方式不能滿足,可以考慮更復(fù)雜的遷移方式。假設(shè)要在遷移過(guò)程中,對(duì)遷移的數(shù)據(jù)進(jìn)行更改,這時(shí)候上面的遷移方案就不能滿足需求了。
對(duì)于上面提到的問(wèn)題,在Mapping Model文件中選中實(shí)體,可以看到Custom Policy這個(gè)選項(xiàng),選項(xiàng)對(duì)應(yīng)的是NSEntityMigrationPolicy的子類(lèi),可以創(chuàng)建并設(shè)置一個(gè)子類(lèi),并重寫(xiě)這個(gè)類(lèi)的方法來(lái)控制遷移過(guò)程。
- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error;