3 回答

TA貢獻1998條經(jīng)驗 獲得超6個贊
我已經(jīng)弄清楚了Apple在其文檔中的提示。實際上,這很容易,但要走很長的路要走。我將通過一個示例來說明該解釋。初始情況是這樣的:
數(shù)據(jù)模型版本1
這是使用“帶有核心數(shù)據(jù)存儲的基于導航的應用程序”模板創(chuàng)建項目時獲得的模型。我編譯了它,并在for循環(huán)的幫助下進行了一些重創(chuàng),以創(chuàng)建大約2k個條目,每個條目都有一些不同的值。在那里,我們以NSDate值進行了2.000個事件。
現(xiàn)在,我們添加數(shù)據(jù)模型的第二個版本,如下所示:
數(shù)據(jù)模型版本2
區(qū)別在于:事件實體不見了,我們有了兩個新實體。一個將時間戳記存儲為a double,第二個將時間戳記存儲為NSString。
目標是將所有版本1事件轉(zhuǎn)移到兩個新實體,并在遷移過程中轉(zhuǎn)換值。這將導致值的兩倍,每個值在單獨的實體中作為不同的類型。
要進行遷移,我們選擇手動遷移,而映射模型就是這樣做。這也是您問題答案的第一部分。我們將分兩步進行遷移,因為遷移2k條目需要花費很長時間,并且我們希望保持較低的內(nèi)存占用。
您甚至可以繼續(xù)拆分這些映射模型,以僅遷移實體范圍。假設我們有100萬條記錄,這可能會使整個過程崩潰。使用Filter謂詞可以縮小獲取的實體的范圍。
回到我們的兩個映射模型。
我們創(chuàng)建第一個映射模型,如下所示:
1.新建文件->資源->映射模型
2.選擇一個名稱,我選擇了StepOne
3.設置源和目標數(shù)據(jù)模型
映射模型第一步
多遍遷移不需要自定義實體遷移策略,但是我們將為該示例提供更多細節(jié)。因此,我們向?qū)嶓w添加了自定義策略。這始終是的子類NSEntityMigrationPolicy。
該策略類實現(xiàn)了一些使遷移發(fā)生的方法。但是,在這種情況下很簡單,因此我們只需要實現(xiàn)一種方法:createDestinationInstancesForSourceInstance:entityMapping:manager:error:。
該實現(xiàn)將如下所示:
StepOneEntityMigrationPolicy.m
#import "StepOneEntityMigrationPolicy.h"
@implementation StepOneEntityMigrationPolicy
- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance
entityMapping:(NSEntityMapping *)mapping
manager:(NSMigrationManager *)manager
error:(NSError **)error
{
// Create a new object for the model context
NSManagedObject *newObject =
[NSEntityDescription insertNewObjectForEntityForName:[mapping destinationEntityName]
inManagedObjectContext:[manager destinationContext]];
// do our transfer of nsdate to nsstring
NSDate *date = [sInstance valueForKey:@"timeStamp"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
// set the value for our new object
[newObject setValue:[dateFormatter stringFromDate:date] forKey:@"printedDate"];
[dateFormatter release];
// do the coupling of old and new
[manager associateSourceInstance:sInstance withDestinationInstance:newObject forEntityMapping:mapping];
return YES;
}
最后一步:遷移本身
我將跳過設置幾乎完全相同的第二個映射模型的部分,只是將NSDate轉(zhuǎn)換為double的timeIntervalSince1970。
最后,我們需要觸發(fā)遷移。我現(xiàn)在暫時跳過樣板代碼。如果您需要,我會在這里發(fā)布??梢栽凇?定制遷移過程”中找到它,它只是前兩個代碼示例的合并。如下第三和最后一部分將被修改:除了使用的類方法的NSMappingModel類mappingModelFromBundles:forSourceModel:destinationModel:,我們會使用initWithContentsOfURL:,因為該類方法將返回只有一個,也許是第一次,發(fā)現(xiàn)映射模型的捆綁。
現(xiàn)在,我們有了兩個映射模型,它們可以在循環(huán)的每個過程中使用,并將遷移方法發(fā)送到遷移管理器。而已。
NSArray *mappingModelNames = [NSArray arrayWithObjects:@"StepOne", @"StepTwo", nil];
NSDictionary *sourceStoreOptions = nil;
NSURL *destinationStoreURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataMigrationNew.sqlite"];
NSString *destinationStoreType = NSSQLiteStoreType;
NSDictionary *destinationStoreOptions = nil;
for (NSString *mappingModelName in mappingModelNames) {
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:mappingModelName withExtension:@"cdm"];
NSMappingModel *mappingModel = [[NSMappingModel alloc] initWithContentsOfURL:fileURL];
BOOL ok = [migrationManager migrateStoreFromURL:sourceStoreURL
type:sourceStoreType
options:sourceStoreOptions
withMappingModel:mappingModel
toDestinationURL:destinationStoreURL
destinationType:destinationStoreType
destinationOptions:destinationStoreOptions
error:&error2];
[mappingModel release];
}
筆記
映射模型以cdm捆綁包結尾。
必須提供目標存儲,并且不應將其作為源存儲。成功遷移后,您可以刪除舊的并重命名新的。
創(chuàng)建映射模型后,我對數(shù)據(jù)模型進行了一些更改,這導致了一些兼容性錯誤,我只能通過重新創(chuàng)建映射模型來解決。

TA貢獻1835條經(jīng)驗 獲得超7個贊
這些問題相關:
在iPhone上遷移大型CoreData數(shù)據(jù)存儲時出現(xiàn)內(nèi)存問題
iOS多通道核心數(shù)據(jù)遷移
引用第一個鏈接:
官方文檔的“多次通過”部分對此進行了討論,但是看起來他們建議的方法是按實體類型劃分遷移,即制作多個映射模型,每個映射模型都從實體模型中遷移實體類型的子集。完整的數(shù)據(jù)模型。
- 3 回答
- 0 關注
- 659 瀏覽
添加回答
舉報