在多线程上下文中,在托管对象上设置属性时,CoreData 阻塞

Posted

技术标签:

【中文标题】在多线程上下文中,在托管对象上设置属性时,CoreData 阻塞【英文标题】:CoreData blocking when setting an attribute on a managed object, in a multithread context 【发布时间】:2011-11-19 22:31:02 【问题描述】:

我在 Core Data 上有一个多线程问题。

一些 NSOperation 在后台使用以下指令更新不同的 NSManagedObject 属性:

BKArtistData *artistData = [self artistDataForName:bandName];
artistData.bandId = bandId;
[self save];

artistDataForName 对所有后台线程共享的上下文执行提取。 (我也尝试了一个上下文一个线程的策略,事情仍然是阻塞的)。

我的问题是只有 1 个线程可以执行更新。其他线程卡在了

artistData.bandId = bandId; 

行。

最终,我可以让更新从主线程执行。不过,您知道阻塞是从哪里来的吗?

【问题讨论】:

【参考方案1】:

Core Data 文档指出 NSManagedObjects 不是线程安全的。除非您为每个线程都有一个单独的 ManagedObjectContext,否则您没有遵循指南,您很可能会遇到问题。

你可以通过在主线程上进行更新来实现你想要的:

dispatch_async(dispatch_get_main_queue(), ^
    artistData.bandId = bandId;
);

但是,仅将此更新推送到主线程可能还不够,因为您传递给后台线程的 NSManagedObject 在您进行此更新之前可能已经在另一个线程中被删除或更改...因此需要单独的 ManagedObjectContexts,然后使用 Core Data 工具来管理更新和处理冲突的更改。

进一步:请仔细阅读您的问题。鉴于您在 ArtistDataForName 中执行提取,您绝对应该为每个线程使用单独的托管对象上下文。

【讨论】:

我确实为每个线程尝试了具有不同上下文的相同代码,但事情仍然阻塞。从主线程进行更新效果很好,我的代码工作正常。不过,我很想知道为什么我的代码不起作用......我会更新我的问题以使其更具体。

以上是关于在多线程上下文中,在托管对象上设置属性时,CoreData 阻塞的主要内容,如果未能解决你的问题,请参考以下文章

在后台线程上安全保存 Core Data 托管对象上下文的正确方法?

Core Data 3 托管对象上下文

托管对象上下文未保存到持久存储

如何正确使用 Core Data 进行多线程处理? [关闭]

Core Data - 批量处理获取结果的属性

在 Core Data 中执行子获取时,在父上下文中修改托管对象是不是会向下传播到子上下文?