1

我的情况是我的应用程序使用核心数据,并且需要从该核心数据加载图像以显示在表格视图中。由于这样做需要时间,它需要在后台线程中运行。所以我有这样的代码:

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

});

这大大加快了该过程,并且图像在准备就绪时出现在背景中。

问题是,有时它会让前台线程与后台线程同时尝试访问核心数据。它不喜欢这样,所以它崩溃了。这一定是很多开发人员都会遇到的情况,因此有一个解决方案。我想知道如何处理这种情况,以便我的应用程序在它们同时开始访问核心数据时停止崩溃?

4

2 回答 2

6

在这里查看我之前的答案

对于核心数据,有一条黄金法则——每个线程一个托管对象上下文。托管对象上下文不是线程安全的,因此如果您在后台任务中工作,您可以使用主线程来避免与 UI 操作的线程冲突,或者创建一个新上下文来完成工作。如果工作需要几秒钟后,您应该执行后者以阻止您的 UI 锁定。

简而言之,您需要创建一个单独的托管对象上下文以在后台线程中使用。然后,您必须在适当的地方将更改合并回原始上下文。

于 2012-05-30T15:21:39.077 回答
1

你需要阅读 Apple 的 Core Data 编程指南。

基本上,NSManagedObjects 和 NSManagedObjectContexts 不是线程安全的。您需要在后台上下文中创建一个新的 NSManagedObjectContext 来完成这项工作。您不能跨线程传递 NSManagedObjects。相反,您可以存储一个 NSManagedObjectID 数组,并使用它从新上下文中“重新加载”对象。

于 2012-05-30T15:22:30.277 回答