我的情况是我的应用程序使用核心数据,并且需要从该核心数据加载图像以在表格视图中显示。由于需要花费时间,因此需要在后台线程中运行。所以我有这样的代码:
dispatch_async(queue, ^{
if (self.cellInfo.numberOfMediaItems > 0) {
int i = 0;
int numberOfThumbnails = MIN(self.cellInfo.numberOfMediaItems, 3);
while (i < numberOfThumbnails) {
Media *media = [self.entry.media objectAtIndex:i];
UIImage *image = [media getThumbnail];
[self.mediaArray addObject:image];
i++;
}
}
dispatch_async(dispatch_get_main_queue(), ^{
self.isFinishedProcessing = YES;
[self setNeedsDisplay];
});
});
这会大大加快处理速度,并且图像在准备就绪时会显示在背景中。
问题是,有时它会让前台线程尝试并在后台线程的同时访问核心数据。它不喜欢这样,所以它崩溃了。这必须是许多开发人员进入的情况,因此需要一个解决方案。我想知道如何处理这种情况,以便我们的应用程序在同时开始访问核心数据时停止崩溃?
答案 0 :(得分:6)
核心数据是一个黄金法则 - 一个托管对象 每线程的上下文。托管对象上下文不是线程安全的,所以如果 你正在后台任务中工作,你要么使用主线程 避免与UI操作发生线程冲突,或者创建新的 工作的上下文。如果工作需要几秒钟 然后你应该做后者来阻止你的UI锁定。
简而言之,您需要创建一个单独的托管对象上下文,以便在后台线程中使用。然后,您必须在适当的时候将更改合并回原始上下文。
答案 1 :(得分:1)
您需要阅读Apple的核心数据编程指南。
基本上,NSManagedObjects和NSManagedObjectContexts不是线程安全的。您需要在后台上下文中创建一个新的NSManagedObjectContext来完成工作。您不能跨线程传递NSManagedObjects。相反,您可以存储一个NSManagedObjectID数组,并使用它来从新上下文“重新加载”对象。