核心数据 - 不能存储两个单独的实体

Posted

技术标签:

【中文标题】核心数据 - 不能存储两个单独的实体【英文标题】:Core Data - cannot store two separate entities 【发布时间】:2013-10-18 10:41:20 【问题描述】:

我的核心数据与一个名为 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

【问题讨论】:

【参考方案1】:

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

只需将新实体添加到现有模型中即可。在这种情况下,您必须删除该应用 在运行新代码之前从模拟器或设备开始新的 与更改的模型兼容的数据库。这通常在开发过程中完成, 当不需要保存数据时。或者: 创建模型版本并在Core Data时添加“轻量级迁移”选项 堆栈被初始化。在这种情况下,旧模型和新模型都被复制到 应用程序包,Core Data 可以(在某些情况下)迁移旧数据库 到一个新的数据库。如果对已分发的应用程序进行更新,则会执行此操作, 并且您希望保留数据。 “轻量级迁移”适用于模型中的简单更改,例如添加新的 实体。 请参阅"Core Data Model Versioning and Data Migration Programming Guide" 了解更多信息。

【讨论】:

我尝试了第一个选项,它可以按要求工作。谢谢! @user2894272:不客气,欢迎来到 Stack Overflow!【参考方案2】:

您的问题是,当您更改模型时,持久存储(即 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];
    

【讨论】:

是的,如果其他一切(如迁移)都失败了,那么重新创建商店可能比让应用崩溃更好。

以上是关于核心数据 - 不能存储两个单独的实体的主要内容,如果未能解决你的问题,请参考以下文章

最佳实践? - 数组/字典作为核心数据实体属性 [关闭]

核心数据实体中的对象数组?

核心数据:写时复制实体?

通过核心数据关系改变属性值

新的核心数据实体与现有实体相同:单独的实体或其他解决方案?

两个日期之间实体属性的核心数据总和