其他线程可以间接访问在自己的线程中运行的托管对象上下文吗?

Posted

技术标签:

【中文标题】其他线程可以间接访问在自己的线程中运行的托管对象上下文吗?【英文标题】:Is it OK for other threads to have indirect access to a managed object context running in a thread of its own? 【发布时间】:2010-09-30 16:25:14 【问题描述】:

Apple 推荐的多线程核心数据方法是为每个线程使用一个托管对象上下文,并通过将更改的线程的上下文保存到共享持久存储中来将更改从一个上下文发送到另一个上下文。

虽然我可以想象这很好,例如。一个 RSS 阅读器,对于某些应用程序来说,它似乎远非理想。就我而言,我正在编写一个音乐音序器,它使用后台线程记录和播放数据。我需要在录制/播放期间主线程可以访问录制的数据。在录制/播放时必须不断保存和加载数据已经够糟糕了,但更糟糕的是,它似乎会迫使用户在录制或播放时进行保存,这有点尖叫“糟糕的应用程序”。

但是,似乎有一种方法可以回避这一点。如果其他线程不需要访问核心数据实体本身(只是它们包含的数据),那么阻止我在自己的线程中运行托管对象上下文,并且只允许其他线程间接访问,例如通过绑定 UI对象到在托管对象上下文的线程上调用 performSelector:onThread:withObject:waitUntilDone: 以获取/设置值的属性?

它并没有提供多线程的一些好处(即将核心数据扩展到多核 CPU),但很多时候,我们只是希望多线程避免在发生密集事件时锁定 UI。

我还没有看到这种支持核心数据的模式。考虑到当你不完全按照苹果的建议去做时,它可能是一个奇怪且不可预测的野兽,我认为这是否真的避免了我们不鼓励让多个线程访问单个托管对象上下文的原因是值得的.

【问题讨论】:

【参考方案1】:

您无法控制 NSManagedObject 内部的实现细节,更具体地说,当您读取属性时,CoreData 可能需要在上下文中执行某些操作是有原因的。

对于您的特定需求,我建议您使用高度优化的隔离、缓冲区和队列解决方案,您可以在将 CD 对象中需要的内容复制到后台处理线程之前将它们复制出来。


您可以根据需要使用 performSelector:on*Thread:,但随后您将处理同步问题、延迟和其他有趣的并发问题。就个人而言,我会使用上述排队机制。

【讨论】:

谢谢。我想我的想法是让多个线程发送 performSelector:onThread... 到 NSManagedObject 会将读/写消息放入队列中,这(我希望)为我们免费提供优化的缓冲区和队列。无论 NSManagedObject 在内部做什么,它都不会运行访问器 #2,直到它使用访问器 #1 完成,对吧?

以上是关于其他线程可以间接访问在自己的线程中运行的托管对象上下文吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个活动访问在一个活动中实例化并在其自己的线程中运行的对象?

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

在后台线程中更新托管对象上下文

线程详解

线程安全

Android中UI线程与后台线程交互设计的6种方法