【问题标题】:NSPrivateQueueConcurrencyType serial or concurrent?NSPrivateQueueConcurrencyType 串行还是并发?
【发布时间】:2017-06-01 18:37:57
【问题描述】:
正如标题所说,问题是,并发类型为NSPrivateQueueConcurrencyType 的NSManagedObjectContext 是串行的还是并发的。
更具体地说,如果我打电话给
[managedObjectContext performBlock:^{
}];
对于一个长时间运行的任务,是否会阻止其他使用 performBlock 对该上下文的调用,直到第一个调用完成?
【问题讨论】:
标签:
objective-c
core-data
【解决方案1】:
是来自Apple docs的串行队列。
或者您可以简单地尝试运行此代码并查看结果。编号将连续打印。
let privateMOC = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
privateMOC.perform {
for i in 0...8000 {
if i.isMultiple(of: 3000) {
print("1")
}
}
}
privateMOC.perform {
for i in 0...8000 {
if i.isMultiple(of: 3000) {
print("2")
}
}
}
【解决方案2】:
我认为这两种方式都没有记录。然而,Core Data 通常不是线程安全的,performBlock 和 performBlockAndWait 方法是处理这种情况的方法——将所有 Core Data 工作放在一个队列中。因此,如果它是一个并发队列,我会感到非常惊讶,因为重点是避免并发。
【解决方案3】:
我在官方文档中找不到任何证据,但最近我与NSPrivateQueueConcurrencyType 合作,我记得它是连续的。 this blog post 还声明:
当使用初始化器 initWithConcurrencyType:NSPrivateQueueConcurrencyType] 或 -[initWithConcurrencyType:NSMainQueueConcurrencyType] 创建 NSManagedObjectContext 时,所有对上下文的访问及其托管对象都必须通过方法 -[performBlock: 或 -[performBlockAndWait:] 。 Core Data 使用串行队列来确保对上下文的操作按顺序执行,并且一次只发生一个操作
【解决方案4】:
这是一个串行队列。当您调用performBlock 和performBlockAndWait 如果您指定NSPrivateQueueConcurrencyType 时,您的代码将连续执行。
Apple 不会在 Apple 的文档中随机选择 PrivateQueue 一词,Private Queue = Serial Queue。看到这里Serial Queue description
串行队列(也称为私有调度队列)按添加到队列的顺序一次执行一项任务。
另外,我在调试中仔细检查了这一点。请参阅以下屏幕截图中的最后一个线程:
【解决方案5】:
NSMainQueueConcurrencyType 使用主队列。主队列绑定到主线程,因此是串行的。
主调度队列是一个全局可用的串行队列,它在应用程序的主线程上执行任务。
【解决方案6】:
我已经测试过所有任务都会按顺序执行,但它可能在不同的线程中执行
backgroundContext.perform {
print("perform------:\(self.number)", Thread.current)
self.number += 1
}