我最近看了今年WWDC GCD的演讲,我认为有一个代码片段有问题。它是关于使用 DispatchQueues 使属性线程安全。
class MyObject {
private var internalState: Int
private let internalQueue: DispatchQueue // Serial or Concurrent?
var state: Int {
get {
return internalQueue.sync { internalState }
}
set (newState) {
internalQueue.sync { internalState = newState }
}
}
}
他们使用 DispatchQueue 来锁定属性。但我认为这个片段是无效的,因为内部队列可能是并发的。因此,如果我们从两个不同的 DispatchQueues/Threads 调用 setter,如果该内部队列不是串行的,它也可能导致线程问题,对吗?因为在我的理解中,同步只是保存调用线程并在任务完成时继续。您如何看待此片段?我错了吗?
我只想展示另一种方法,它使您能够并发阅读,但在使用调度屏障写入时阻止所有内容。
class MyObject {
private var internalState: Int
private let internalQueue = DispatchQueue(label: "reader-writer", attributes: .concurrent)
var state: Int {
get {
return internalQueue.sync { internalState }
}
set (newState) {
internalQueue.async(flags: .barrier) { internalState = newState }
}
}
}
使用这种方法,读取可以在队列上并发发生,但由于存在障碍,写入是以独占方式执行的。
这只是 Matt Galloway 撰写的《Effective Objective C 2.0》一书中解释的方法的 Swift 3 转换。
但我认为这个代码段是无效的,因为内部队列可能是并发的
但它不是并发的。默认情况下,您创建的调度队列是串行的。这就是技术(和示例)的重点。