使用 GCD 的核心数据

Posted

技术标签:

【中文标题】使用 GCD 的核心数据【英文标题】:Core data with GCD 【发布时间】:2017-03-30 06:15:58 【问题描述】:

我正在用核心数据探索 GCD。我知道托管对象上下文不是线程安全的。

我使用选项“NSPrivateQueueConcurrencyType”创建了私有上下文。根据文档,我必须使用 performBlock 或 performBlockAndWait 对上下文执行任何操作,它将在自己的私有线程中执行该操作。我的问题是,

    在执行块中我必须执行哪些操作?是只访问上下文对象还是使用托管对象? 即使我在“DispatchQueue.global().async”中向数据库插入一个新对象(不使用执行块),它也可以正常工作。为什么? (这是一个不同的线程) 如果我们使用“NSPrivateQueueConcurrencyType”创建上下文,可以在不同的线程中进行数据库操作吗?

我可以为每个数据库操作使用执行块,但是我们的项目已经有很多代码在私有队列中运行。请帮助我更好地理解这一点。

【问题讨论】:

【参考方案1】:

此答案是 Sandeep Bhandari 给出的答案的结论。在这里,我假设每个人都清楚线程和队列的概念。

在任何时间点都应该从单个线程访问始终管理的对象上下文,因为它不是线程安全的。如果我们在多个线程中使用上下文,我们应该确保它是序列化的,这样没有两个线程同时访问同一个上下文。如果这样做,它将崩溃。

ios 5 及更高版本,Apple 提供了 3 种创建上下文的方法。

    confinement​Concurrency​Type(在 iOS 10 中已弃用):如果您使用此选项创建上下文,则您有责任确保您在线程中执行所有数据库操作这创造了这个背景。

    private​Queue​Concurrency​Type:如果我们使用此选项创建上下文,它将创建自己的内部队列来创建此上下文并确保所有数据库操作发生在同一个线程中。仅当您在 performBlockperformBlockAndWait 中使用此上下文执行所有任务时,它才会使用内部队列。如果您正在使用任何其他队列对此上下文执行任何数据库操作,如果没有两个线程同时访问,它将起作用。如果两个线程正在访问它,这将崩溃。管理这一点非常困难,因为该任务执行发生在运行时取决于资源可用性。这种类型的问题不能那么容易地重现。因此,请使用那些 performBlock API 来使用此上下文执行任何数据库操作。

    ma​​in​Queue​Concurrency​Type:如果您使用此选项创建上下文,它将在主线程中创建托管对象上下文。您需要在主线程中使用此上下文执行任何数据库操作。您也可以在此处使用 performBlock 来确保所有任务都发生在主线程中。如果没有两个线程同时访问,即使使用此上下文执行任何操作也可以在其他线程中正常工作。

【讨论】:

以上是关于使用 GCD 的核心数据的主要内容,如果未能解决你的问题,请参考以下文章

iOS核心笔记——多线程-GCD

iOS:将 GCD 与 Core Data 结合使用

ios多线程操作—— GCD核心概念

iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

iOS 多线程之GCD的使用

iOS 多线程GCD的基本使用