自定義遷移過(guò)程
如果你像自己?jiǎn)?dòng)遷移,你只需要自定義遷移過(guò)程即可掏颊。你可以這樣做糟红,例如,在應(yīng)用程序的主包意外的位置搜索模型乌叶,或者通過(guò)使用不同的映射模型執(zhí)行多次傳遞來(lái)處理大型數(shù)據(jù)集(詳情可以參閱Mtltiple Passes - Dealing With Large Detasets)盆偿。
是否需要遷移(Is Migration Necessary)
在啟動(dòng)遷移過(guò)程之前,你應(yīng)首先確定是否需要遷移准浴。你可以檢查 NSManagedObjectModel的isConfiguration:CompatibleWithStoreMetadata:如7 -1所示:
Listing 7-1 Checking whether migration is 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
}
初始化遷移管理器
使用initWithSourceModel: destinationModel: 的方法初始化遷移管理器事扭;因此首先需要找到合適的儲(chǔ)存模型。使用NSManagedObjectModel的ModelFromBundles:forStoreMetadata:的方法獲得儲(chǔ)存模型乐横。如果返回一個(gè)合適的模型求橄,那么就可以創(chuàng)建遷移管理器今野。如7 - 2所示:
Listing 7-2 Initializing a Migration Manager
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];
進(jìn)行遷移
遷移儲(chǔ)存使用NSMigrationManager的migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destinationOptions:error:的方法。要使用這個(gè)方法罐农,需要編組以些參數(shù)条霜;大多數(shù)是直接的,唯一需要一些工作的是發(fā)現(xiàn)適當(dāng)?shù)挠成淠P停梢允褂肗SMappingModels的mappingModelFromBundles:forSourceModel:destinationModel:方法)涵亏。如 7- 3所示宰睡。(接上7 - 2)。
Listing 7-3 Performing a Migration
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
上面所示的基本方法是讓遷移管理器使用兩個(gè)數(shù)據(jù)模型气筋,然后迭代映射模型中提供的步驟(映射)拆内,以將數(shù)據(jù)從一側(cè)移動(dòng)到下一個(gè)(另一側(cè))。 因?yàn)镃ore Data執(zhí)行“三階段”遷移宠默。其中它首先創(chuàng)建所有數(shù)據(jù)麸恍,然后在第二階中段關(guān)聯(lián)數(shù)據(jù) - 它必須維護(hù)“關(guān)聯(lián)表”(它指出目標(biāo)儲(chǔ)存中的哪個(gè)對(duì)象是被遷移的源代碼儲(chǔ)存中的對(duì)象的版本,反之亦然)光稼,此外或南,由于它沒(méi)有一中方法來(lái)刷新正在使用的上下文,這意味著將在遷移過(guò)程中艾君,遷移管理器中會(huì)積累許多對(duì)象采够。
為了解決這個(gè)問(wèn)題,映射模型作為參數(shù)冰垄,在migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destinationOptiuons:error:方法中調(diào)用本身蹬癌。這意味著如果你可以隔離圖形(graph)的一部分(就映射而言),并在單獨(dú)的映射模型中創(chuàng)建他們虹茶,則可以執(zhí)行一下操作:
- 獲取源和目標(biāo)數(shù)據(jù)模型
- 與他們創(chuàng)建一個(gè)遷移管理器
- 查找所有映射模型逝薪,并將他們放到數(shù)組中(如果需要的話,按照一定順序排列)
- 循環(huán)遍歷數(shù)組蝴罪,并調(diào)用migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destiantionOptions:error的方法用于每個(gè)映射董济。
這允許你一次遷移數(shù)據(jù)的一個(gè)“塊”,而不是立即拉入所有的數(shù)據(jù)要门。從“跟蹤/顯示進(jìn)度”的角度來(lái)看虏肾,這基本上只是創(chuàng)造另一層工作,所以你可以根據(jù)迭代的映射模型的數(shù)量來(lái)確定完成的百分比欢搜。