4

Core Dataを使用してモデルから単純なデータをロードし、それをテーブルビューに配置しようとしています。これが私の永続ストアの次のコードです。

//AppDelegate.m

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

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"vofasmmmnmgd.sqlite"];

if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {
    NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"CoreDataSQLite" ofType:@"sqlite"]];
    NSError* err = nil;

    if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&err]) {
        NSLog(@"Oops, could copy preloaded data");
    }
}

NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
{

    /* Replace this implementation with code to handle the error appropriately.

     abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

     Typical reasons for an error here include:
     * The persistent store is not accessible;
     * The schema for the persistent store is incompatible with current managed object model.
     Check the error message to determine what the actual problem was.


     If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.

     If you encounter schema incompatibility errors during development, you can reduce their frequency by:
     * Simply deleting the existing store:
     [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]

     * Performing automatic lightweight migration by passing the following dictionary as the options parameter:
     [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

     Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
     */

    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
 }

  return __persistentStoreCoordinator;
}

ご覧のとおり、sqliteデータベースからデータをプリロードしています。すべてが完璧に機能します。モデルからデータを取得して正しく表示することができました。

しかし

アプリケーションの最後の部分で同じモデルに2つ目のエンティティを追加すると、状況が変わりました。アプリは「abort();」でクラッシュすることを決定します。次のように言っています:

"The model used to open the store is incompatible with the one used to create the store";

これは、Googleの調査でわかったように、簡単な修正です。アプリに移動して削除すると、すべてのデータベースのデータがリセットされ、リロードされます。しかし、私はそれを行いましたが、それでも機能しません。これが私が試したすべてで、まだ同じ結果です:

  • アプリを削除する
  • iPhoneシミュレーターのコンテンツと設定をリセットする
  • storeURLの名前を元の値以外の名前に変更します。
  • 上記のコードのコメントにリストされているストアURLを削除する
  • プロジェクトのクリーニング

別のエンティティを追加したのは、エンティティを削除すると完全に実行され、問題なく通常に戻るためであるという結論に達しました。

これを修正する方法がわからないので、何が起こっているのか非常にイライラするのかわかりません。グーグルはこの問題の解決策を使い果たしているので、私はこの欲求不満を終わらせるための奇跡的な解決策を得るために素晴らしいスタックオーバーフローに乗るだろうと思いました。ありがとう!

4

1 に答える 1

8

動機は非常に単純です。モデルを変更すると、CoreDataはモデルをマップする方法を認識しません。

CoreDataドキュメントから直接

したがって、モデルを変更すると、以前に作成したストアと互換性がなくなります(したがって、開くことができなくなります)。したがって、モデルを変更する場合は、既存のストアのデータを新しいバージョンに変更する必要があります。ストアの形式を変更することを移行と呼びます。

あなたがYESのために設定した場合NSMigratePersistentStoresAutomaticallyOptionNSInferMappingModelAutomaticallyOptionあなたは大丈夫なはずです。これは、LightWeight移行とも呼ばれます。

NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setValue:[NSNumber numberWithBool:YES]
            forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setValue:[NSNumber numberWithBool:YES]
           forKey:NSInferMappingModelAutomaticallyOption];
NSPersistentStore *store = nil;
store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType
                                        configuration:nil
                                                  URL:storeURL
                                              options:options
                                                error:&error];

編集

次のスニペットで作成されたoptions辞書をに渡すだけです。addPersistentStoreWithType:configuration:URL:options:error

NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setValue:[NSNumber numberWithBool:YES]
           forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setValue:[NSNumber numberWithBool:YES]
           forKey:NSInferMappingModelAutomaticallyOption];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {

}
于 2013-01-06T14:02:11.413 に答える