我正在使用核心数据探索 GCD。我知道托管对象上下文不是线程安全的。
我使用选项“NSPrivateQueueConcurrencyType”创建了私有(private)上下文。根据文档,我必须使用 performBlock 或 performBlockAndWait 对上下文执行任何操作,它将在自己的私有(private)线程中执行该操作。我的问题是,
- 我必须在 perform block 中执行哪些操作?是只访问上下文对象还是同时使用托管对象?
- 即使我在“DispatchQueue.global().async”(不使用执行 block )中向数据库插入一个新对象,它也能正常工作。为什么? (这是一个不同的线程)
- 如果我们使用“NSPrivateQueueConcurrencyType”创建上下文,那么在不同的线程中执行数据库操作可以吗?
我可以为每个数据库操作使用执行 block ,但我们的项目已经有很多代码在私有(private)队列中运行。请帮助我更好地理解这一点。
最佳答案
此答案是 Sandeep Bhandari 给出的答案的结论。在这里我假设每个人都清楚 Thread 和 Queue 的概念。
始终托管对象上下文应该在任何时间点从单线程访问,因为它不是线程安全的。如果我们在多线程中使用上下文,我们应该确保它是序列化的,这样就不会有两个线程同时访问同一个上下文。如果这样做,它将崩溃。
iOS 5 及更高版本,Apple 提供了 3 种创建上下文的方法。
confinement Concurrency Type(在 iOS 10 中已弃用):如果您使用此选项创建上下文,则您有责任确保您在一个线程中执行所有数据库操作这创造了这个背景。
private Queue Concurrency Type:如果我们使用此选项创建上下文,它将创建自己的内部队列来创建此上下文并确保所有数据库操作发生在同一个线程中。仅当您在 performBlock 或 performBlockAndWait 中使用此上下文执行所有任务时,它才会使用内部队列。如果您正在使用任何其他队列在此上下文中执行任何数据库操作,如果没有两个线程同时访问,它将起作用。如果两个线程正在访问它,这将崩溃。这很难管理,因为任务执行发生在运行时,具体取决于资源可用性。此类问题无法轻易重现。因此,使用那些 performBlock API 在此上下文中执行任何数据库操作。
main Queue Concurrency Type:如果您使用此选项创建上下文,它将在主线程中创建托管对象上下文。您需要在主线程中使用此上下文执行任何数据库操作。您也可以在此处使用 performBlock 来确保所有任务都在主线程中进行。如果没有两个线程同时访问,即使使用此上下文执行任何操作也可以在其他线程中正常工作。
关于ios - GCD 的核心数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43109924/