1

iOS プロジェクトでコア データを使用しています。データモデルのバージョン間でスキーマを移行するために軽量移行を使用しています。フィールドでリリースされるアプリの現在のモーダル バージョンとしてバージョン 3.5 を設定しました。データモデル スキーマに新しい変更を加える前に、新しいデータモデル バージョン 3.6 を作成し、新しいデータモデルに新しいエンティティといくつかの属性の更新を追加しました。すべての変更を完了した後、3.5 から 3.6 への新しいマッピング モデルを作成しました。また、軽量移行のために次のコードを使用しています。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator != nil)
{
    return _persistentStoreCoordinator;
}

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:PERSISTENT_STORE_FILENAME];
NSDictionary *storeOptions = nil; 

NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:storeOptions error:&error])
{

    BOOL shouldPerformLightWeightMigration;

    if (self.optionalCoreDataMigrationHandler) {
        shouldPerformLightWeightMigration = optionalCoreDataMigrationHandler();
    }

    if (shouldPerformLightWeightMigration) {
        [self performLightweightMigrationInBackgroundWithStoreURL:storeURL];
    }        
}    

return _persistentStoreCoordinator;

}

- (void)performLightweightMigrationInBackgroundWithStoreURL:(NSURL *)storeURL {
[self.initializerDelegate willStartMigration];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(void){
    NSDictionary *storeOptions = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

    NSError *error = nil;
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:storeOptions error:&error]) {
        dispatch_async(dispatch_get_main_queue(), ^(void){
            [self.initializerDelegate didFinishMigrationSuccessfully:NO];
        });
    } else {
        dispatch_async(dispatch_get_main_queue(), ^(void){
            [self.initializerDelegate didFinishMigrationSuccessfully:YES];
        });
    }
});

}

既存のアプリの上に新しいアプリをインストールすると、アプリが空白になり、データが取得されず、NSManagedObjectContextDidSaveNotification が呼び出されたときに次のエラーが発生しました。

NSManagedObjectContextDidSaveNotification のオブザーバーが不正に例外をスローしました。保存されたオブジェクト = {....} および例外 = オブジェクトの永続ストアは、この NSManagedObjectContext のコーディネーターから userInfo = (null) で到達できません

別のアプリでも同じプロセスが通常機能します。しかし、何らかの理由でここでは機能しませんでした。過去に、他のアプリでも同様の問題がありました。v1 から v2 へのデータモデルの移行が失敗したため、v1 をソースとして新しいモデル バージョン v3 を作成し、v3 ですべてのデータモデルの更新をやり直し、v1 から v3 への新しいマッピング モデルを作成しました。その後、軽量の移行が機能しました。

現在のシナリオでは、私は上記のアプローチに従う立場にありません。データモデルを頻繁に更新するため、現在の移行の問題の解決と、将来このような問題を回避するためのその他のベスト プラクティスの解決にご協力ください。

4

0 に答える 0