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

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

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

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

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

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

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

  1. 主要托管对象上下文:

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

    }

  2. 后台托管对象上下文:

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

    }

  3. 更新记录:

    -(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];
        });
    }];
    

    }

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

【问题讨论】:

    标签: ios iphone core-data


    【解决方案1】:

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

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

    更新

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

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

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

    【讨论】:

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