3

我的核心数据使用一个名为 THSettings 的实体正常工作(加载、保存)。

但是,我想创建另一个不相关的核心数据实体,称为 THDetails。

当我在同一个 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

您需要定义一个定义所有实体的模型。如果您向模型添加额外的实体,您有两种选择:

  • 只需将新实体添加到现有模型中即可。在这种情况下,您必须在运行新代码之前从模拟器或设备中删除应用程序,以使用与更改的模型兼容的新数据库开始。这通常在开发过程中完成,此时不需要保留数据。或者:
  • 创建模型版本并在 Core Data 堆栈初始化时添加“轻量级迁移”选项。在这种情况下,新旧模型都被复制到应用程序包中,Core Data 可以(在某些情况下)将旧数据库迁移到新数据库。如果对已分发的应用程序进行了更新,并且您希望保留数据,则可以这样做。“轻量级迁移”适用于模型中的简单更改,例如添加新实体。有关详细信息,请参阅“核心数据模型版本控制和数据迁移编程指南”
于 2013-10-18T10:58:53.617 回答