IOS:在API调用之后,可以在后台线程中完成对Core Data的更新吗?

时间:2016-12-27 21:10:54

标签: ios core-data nsurlsession

作为同步操作的一部分,我按照this answer的建议使用NSSession对象从API中获取大量数据:

 NSURLSession *session = [NSURLSession sharedSession];
        NSURLSessionDataTask *data = [session dataTaskWithURL:dataUrl completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            // use `Data` here
             if (data !=nil) {
             [self processData:data];//this currently includes saving to CoreData
            }
            // finally, any UI/model updates should happen on main queue

            dispatch_async(dispatch_get_main_queue(), ^{
                //do what you want with data
                NSLog(@"back in main queue");
                if (data==nil) {
                    NSLog(@"no data from api");
                }
                else {
                    [self.tableView setNeedsDisplay];
                    [self.tableView reloadData];
                }
            });
        }];

        [data resume];

我的问题是,可以在后台线程中将数据保存到CoreData,还是在完成块/主线程中更好?现在我在后台线程中这样做。然而,在tableview完全加载之前有一个很长的延迟,并且作为故障排除的一部分 - 我发现这可能是问题所在。

感谢您的建议。

1 个答案:

答案 0 :(得分:0)

您不应该在主线程上执行此操作。但是,您应该如何实现它取决于您的Core Data堆栈以及您在processData函数中实际执行的操作。通常,在这些导入方案中,最佳做法是从专用队列上的子上下文执行保存操作。

Apple有一些示例代码here

摘录该页面:

  

在此示例中,最初作为JSON有效负载接收数据数组。然后,您创建一个新的NSManagedObjectContext,它定义为专用队列。新上下文设置为运行应用程序的主队列上下文的子级。从那里你调用performBlock:并在传递给performBlock的块内部进行实际的NSManagedObject创建。一旦消耗了所有数据并将其转换为NSManagedObject实例,就可以在私有上下文上调用save,这会将所有更改移动到主队列上下文中而不会阻塞主队列。