ren*_*ene 15 core-data thread-safety grand-central-dispatch ios
我开始认为我的问题的答案是"不",但我仍然对此感到困惑和不确定.所以请确认.我已经了解了在使用多线程的Core Data时要小心.NSManagedObjectContext对象不得跨越线程边界.作为一个同时具有线程和核心数据的新手,我很高兴地发现GCD应该可以使其中的一些变得更容易.
或许,我想我会简单地创建一个专用的GCD调度队列来处理核心数据(如果需要,甚至可以有多个调度队列,每个队列都有自己的核心数据上下文).那会很简单.
但现在我意识到GCD调度队列的一大优势是它根据需要管理和使用多个线程.所以 - 如果我理解这一点 - 我交给同一个调度队列的任务最终可能会在不同的线程中运行,可能会将核心数据上下文从一个线程切换到另一个线程,并且出现问题.是对的吗?
我已经阅读了许多相关的问题和答案,例如Core Data和threads/Grand Central Dispatch,但我仍然有些困惑.使用GCD队列接受的问题答案确实确保在每个线程上创建新的上下文,但没有指出这样做的必要性.另一个答案是"您可以在名为com.yourcompany.appname.dataaccess的队列上执行所有CoreData工作",这似乎暗示只要Core Data工作仅限于一个GCD调度队列,那么一切正常.也许不是.
Cal*_*leb 20
更新:正如@adib在评论中指出的那样,在iOS 9和MacOS X 10.11中,序列化托管对象上下文访问的方法已经改变.NSConfinementConcurrencyType,线程限制策略现在已被弃用,有利于NSPrivateQueueConcurrencyType和NSMainQueueConcurrencyType.换句话说,停止使用线程并发访问Core Data对象,而是开始使用GCD.您应该使用主调度队列或与MOC关联的队列,具体取决于您配置MOC的方式,而不是您自己创建的队列.使用NSManagedObject -performBlock:或-performBlockAndWait:方法很容易做到这一点.
简短回答:使用串行调度队列可以提供对托管对象上下文的序列化访问,这是实现"线程限制"策略的可接受方式,即使GCD实际上可能使用多个线程.
更长的回答:
使用GCD队列接受的问题答案确实确保在每个线程上创建新的上下文,但没有指出这样做的必要性.
你需要记住的最重要的事情是,你必须避免修改从两个不同的线程管理对象范围内的同时.这可能会使上下文陷入一种不一致的状态,并且没有任何好处.因此,您使用的调度队列类型很重要:并发调度队列将允许多个任务同时进行,如果它们都使用相同的上下文,您将遇到麻烦.另一方面,如果使用串行调度队列,则可能在不同的线程上执行两个或多个任务,但任务将按顺序执行,并且一次只能运行一个任务.这与在同一个线程上运行所有任务非常相似,至少就维护上下文的一致性而言.
这就是Core Data一直以来的工作方式.该核心数据并发的核心数据编程指南的部分提供了有关如何,如果你决定使用在多线程一个上下文进行咨询.它主要讨论在您访问它时需要非常小心地锁定上下文.但是,所有锁定的关键是要确保两个或多个线程不会同时尝试使用上下文.使用序列化调度队列实现了相同的目标:因为队列中一次只执行一个任务,所以两个或多个任务不可能同时尝试使用上下文.
| 归档时间: |
|
| 查看次数: |
4643 次 |
| 最近记录: |