核心数据数据未保存

Posted

技术标签:

【中文标题】核心数据数据未保存【英文标题】:Core data data not saved 【发布时间】:2014-01-16 09:01:54 【问题描述】:

我目前正在开发一个使用 Core Data 来存储数据的应用程序。该应用程序通过下载和解析一个巨大的 XML 文件(大约 40000 个条目)将其内容与 Web 服务器同步。该应用程序允许用户搜索数据并对其进行修改 (CRUD)。提取操作太繁重,这就是我决定使用以下模式的原因:

“主线程的一个托管对象上下文 (NSMainQueueConcurrencyType) 以刷新用户界面。繁重的获取和更新是通过多个后台托管对象上下文 (NSPrivateQueueConcurrencyType) 完成的。不使用子上下文”。

我将一些对象提取到一个数组中(让我们说“用户”数组),然后我尝试在后台上下文中更新或删除一个“用户”(对象“用户”是从填充的数组中获得的)和最后我保存了那个上下文。

我正在收听 NSManagedObjectContextDidSaveNotification 并将所有修改与我的主线程托管对象上下文合并。

一切正常,除非当我重新启动我的应用程序时,我意识到没有保存任何修改。

这里有一些代码来解释使用的模式

    主要托管对象上下文:

    -(NSManagedObjectContext *)mainManagedObjectContext 
    
    if (_mainManagedObjectContext != nil)
    
        return _mainManagedObjectContext;
    
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    
    _mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [_mainManagedObjectContext setPersistentStoreCoordinator:coordinator];
    
    return _mainManagedObjectContext;
    

    后台托管对象上下文:

    -(NSManagedObjectContext *)newManagedObjectContext 
    
    NSManagedObjectContext *newContext;
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    
    newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [newContext performBlockAndWait:^
    
        [newContext setPersistentStoreCoordinator:coordinator];
    ];
    
    return newContext;
    

    更新记录:

    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    
    FootBallCoach *coach = [_coaches objectAtIndex:indexPath.row];
    coach.firstName = [NSString stringWithFormat:@"Coach %i",indexPath.row];
    
    NSManagedObjectContext *context = [[SDCoreDataController sharedInstance] newManagedObjectContext];
    [context performBlock:^
    
        NSError *error;
        [context save:&error];
    
    
        if (error)
        
            NSLog(@"ERROR SAVING : %@",error.localizedDescription);
        
    
        dispatch_async(dispatch_get_main_queue(), ^
            [self refreshCoaches:nil];
        );
    ];
    

我错过了什么吗?我应该在保存后台上下文后保存我的主要托管对象上下文吗?

【问题讨论】:

【参考方案1】:

如果您的上下文配置了持久存储协调器,那么 save 应该将数据写入存储。如果您的上下文配置了另一个上下文作为父级,那么 save 会将数据推送到父级。只有当最后一个父节点,即配置了持久存储协调器的父节点保存时,才会将数据写入存储。

    检查您的后台上下文是否确实配置了持久存储协调器。 检查-save:的返回值和可能的错误。 确保您通过 -performBlock...: 方法使用背景上下文。

更新

每次调用-newManagedObjectContext 方法时,都会创建一个新上下文。这个上下文对你正在更新的 FootBallCoach 对象一无所知。您需要保存FootBallCoach 对象所属的相同上下文。

不要忘记每个对象只属于一个上下文。

还要确保你持有对正在使用其对象的上下文的强引用。

【讨论】:

我编辑了我的问题并添加了一些示例代码。如您所见,没有父子上下文模式,保存错误为零。 您每次都在创建新的上下文。更新了答案。 FootBallCoach 对象是在主上下文中获取的。所以你的意思是我应该保存主要上下文? 是的,因为每个对象只属于一个上下文。更改对象后,您需要保存其上下文,而不是另一个。 谢谢先生。我想知道您是否可以提供一些有关 Core Data 最佳实践的文档。我对遵循的最佳方法完全感到困惑。我阅读了很多文章,嵌套上下文模式存在很多性能问题。我的方法是否被认为是 fetch 和 CRUD 操作的最佳方法?我必须使用多个上下文吗? (我的应用与网络服务器同步,处理大量数据)。

以上是关于核心数据数据未保存的主要内容,如果未能解决你的问题,请参考以下文章

未保存到核心数据数据库的对象

核心数据未保存在分发版本中

核心数据数据未保存

获取未保存数据时的奇怪核心数据行为

核心数据一对多关系未正确/按预期保存

创建了核心数据实体但未保存属性