IOS: 在 API 调用之后,核心数据的更新可以在后台线程中完成吗?

IOS: After API call, may updates to Core Data be done in background thread?

作为同步操作的一部分,我使用 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 是否可以,还是在完成 block/main 线程中保存数据更好?现在我正在后台线程中进行。但是,在 tableview 完全加载之前有很长的延迟,并且作为对此进行故障排除的一部分——我想到这可能是问题所在。

感谢您的建议。

你不应该在主线程上这样做。但是您应该如何实现它取决于您的核心数据堆栈以及您在 processData 函数中实际执行的操作。通常,在这些导入场景中,最佳做法是从私有队列的子上下文执行保存操作。

Apple 有一些示例代码 here

该页面的摘录:

In this example an array of data has been originally received as a JSON payload. You then create a new NSManagedObjectContext that is defined as a private queue. The new context is set as a child of the main queue context that runs the application. From there you call performBlock: and do the actual NSManagedObject creation inside of the block that is passed to performBlock:. Once all of the data has been consumed and turned into NSManagedObject instances, you call save on the private context, which moves all of the changes into the main queue context without blocking the main queue.