在 Swift 中创建线程安全读取时,为什么在并发队列之外创建变量?
When creating thread safe reads in Swift, why is a variable create outside the concurrent queue?
public class Account {
// MARK: Initializer
// Custom initializer
// MARK: Stored Properties
let concurrentQueue: DispatchQueue = DispatchQueue(
label: "concurrentQueue",
qos: DispatchQoS.userInitiated,
attributes: [DispatchQueue.Attributes.concurrent]
)
private var _name: String
public name: String {
get {
return self.concurrentQueue.sync { return self._name }
}
set {
self.concurrentQueue.async(flags: .barrier) {
self._name = newValue
}
}
}
}
假设您有一个像上面那样的 class 线程安全。
Account
class中的getter和这样定义getter有什么区别?
get {
var result: String!
self.concurrentQueue.sync { result = self._name }
return result
}
我目前正在全神贯注于线程安全,我总是看到像后者那样创建读取。在我看来它们几乎是一样的...我错了吗?
来源:GCD Tutorial
没有区别。有两种DispatchQueue.sync
方法:
public func sync(execute block: () -> Swift.Void)
public func sync<T>(execute work: () throws -> T) rethrows -> T
在你的第一个例子中使用了第二个:闭包可以 return 一个值,然后变成 return
sync
调用的值。因此在
get {
return self.concurrentQueue.sync { return self._name }
}
sync { ... }
的 return 值是 self._name
也就是 returned
来自 getter 方法。这相当于(但比)存储
临时变量中的值(这里是闭包 returns Void
):
get {
var result: String!
self.concurrentQueue.sync { result = self._name }
return result
}
当然这只适用于同步调度的闭包,
不是异步调用。这些存储起来供以后执行,必须
return Void
:
public func async(..., execute work: @escaping @convention(block) () -> Swift.Void)
public class Account {
// MARK: Initializer
// Custom initializer
// MARK: Stored Properties
let concurrentQueue: DispatchQueue = DispatchQueue(
label: "concurrentQueue",
qos: DispatchQoS.userInitiated,
attributes: [DispatchQueue.Attributes.concurrent]
)
private var _name: String
public name: String {
get {
return self.concurrentQueue.sync { return self._name }
}
set {
self.concurrentQueue.async(flags: .barrier) {
self._name = newValue
}
}
}
}
假设您有一个像上面那样的 class 线程安全。
Account
class中的getter和这样定义getter有什么区别?
get {
var result: String!
self.concurrentQueue.sync { result = self._name }
return result
}
我目前正在全神贯注于线程安全,我总是看到像后者那样创建读取。在我看来它们几乎是一样的...我错了吗?
来源:GCD Tutorial
没有区别。有两种DispatchQueue.sync
方法:
public func sync(execute block: () -> Swift.Void)
public func sync<T>(execute work: () throws -> T) rethrows -> T
在你的第一个例子中使用了第二个:闭包可以 return 一个值,然后变成 return
sync
调用的值。因此在
get {
return self.concurrentQueue.sync { return self._name }
}
sync { ... }
的 return 值是 self._name
也就是 returned
来自 getter 方法。这相当于(但比)存储
临时变量中的值(这里是闭包 returns Void
):
get {
var result: String!
self.concurrentQueue.sync { result = self._name }
return result
}
当然这只适用于同步调度的闭包,
不是异步调用。这些存储起来供以后执行,必须
return Void
:
public func async(..., execute work: @escaping @convention(block) () -> Swift.Void)