3

THSettings と呼ばれる 1 つのエンティティを使用して、Core Data が正しく機能しています (読み込み、保存)。

ただし、THDetails という別の無関係な Core Data エンティティを作成したいと考えています。

同じ xcdatamodeld ファイルで別のエンティティを作成すると、アプリの実行時に次のエラーが表示されます:「ストアを開くために使用されるモデルは、ストアの作成に使用されるモデルと互換性がありません」。

したがって、そのエンティティを削除し、新しいエンティティ用に別の xcdatamodeld ファイルを作成したところ、次のエラーが発生しました: " *キャッチされない例外 'NSInternalInconsistencyException' が原因でアプリを終了しています。理由: 'NSFetchRequest は、エンティティ名 'THDetails'' の NSEntityDescription を見つけられませんでした""

これがうまくいかない理由を誰か教えてください。複数の無関係なエンティティを保存できるはずです...

THDetails をロードするコードは次のとおりです。

-(NSMutableArray *)loadSavedNotes {
    THAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *moc = [appDelegate managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"THDetails"];
    NSMutableArray *detailsList = [[moc executeFetchRequest:fetchRequest error:nil] mutableCopy];
    NSLog(@"%d", [detailsList count]);
    return detailsList;
}

THSettings をロードするコードは次のとおりです。

THAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *moc = [appDelegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"THSettings"];
NSMutableArray *settingsList = [[moc executeFetchRequest:fetchRequest error:nil] mutableCopy];


// ... process it
4

2 に答える 2

1

問題は、モデルを変更すると、永続ストア (つまり、sqlite データベース) が変更されたモデルと互換性がなくなることです。このタイプのエラーを処理するには、いくつかの方法があります。たとえば、軽量の移行を実行する場合です。

最も簡単な方法は、単純に永続ストアを再作成することです。

NSError *error = nil;
NSURL *storeURL = ...;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] 
                     initWithManagedObjectModel:[self managedObjectModel]];

// if storeCoordinator can't open at storeURL for some reason
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 
                                               configuration:nil 
                                                         URL:storeURL 
                                                     options:nil 
                                                       error:&error]) 
{
    // if there is a database - it means it's the problem - delete it
    if ([[NSFileManager defaultManager] fileExistsAtPath:storeURL.path]) 
    {
        [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];

        // if storeCoordinator still can't open a database, means some other error
        if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 
                                                       configuration:nil 
                                                                 URL:storeURL 
                                                             options:nil 
                                                               error:&error]) 
        {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Database structure has changed. All information had been erased"
                                                             message:nil
                                                            delegate:nil
                                                   cancelButtonTitle:@"OK"
                                                    otherButtonTitles:nil, nil;
        [alertView show];
    }
}
于 2013-10-18T11:13:46.647 に答える
1

すべてのエンティティを定義するモデルを定義する必要があります。モデルに追加のエンティティを追加する場合、次の 2 つのオプションがあります。

  • 新しいエンティティを既存のモデルに追加するだけです。この場合、新しいコードを実行して、変更されたモデルと互換性のある新しい新しいデータベースで開始する前に、シミュレーターまたはデバイスからアプリを削除する必要があります。これは通常、データを保持する必要がない開発中に行われます。また:
  • モデルバージョンを作成し、Core Data スタックの初期化時に「軽量移行」オプションを追加します。この場合、古いモデルと新しいモデルの両方がアプリケーション バンドルにコピーされ、Core Data は (いくつかの条件下で)古いデータベースを新しいデータベースに移行できます。これは、既に配布されているアプリの更新が行われ、データを保持したい場合に行われます。「軽量移行」は、新しいエンティティの追加など、モデルの単純な変更に対して機能します。詳細については、「コア データ モデルのバージョン管理およびデータ移行プログラミング ガイド」を参照してください。
于 2013-10-18T10:58:53.617 に答える