在多线程上下文中,在托管对象上设置属性时,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 托管对象上下文的正确方法?