simplest way is using a serial queue
import Dispatch
struct S {
private var i: Int = 0 {
didSet {
print("someone did set new value:", i)
}
}
private let queue = DispatchQueue(label: "private", qos: .userInteractive) // high priority
var value: Int {
get {
return queue.sync {
return i
}
}
set {
if newValue == value {
return
}
queue.sync {
i = newValue
}
}
}
}
more advanced example use concurrent reading and sync barrier for writing
import Dispatch
struct S {
private var i: Int = 0 {
didSet {
print("someone did set new value:", i)
}
}
private let queue = DispatchQueue(label: "private", qos: .userInteractive, attributes: .concurrent) // high priority
var value: Int {
get {
return queue.sync {
return i
}
}
set {
if newValue == value {
return
}
queue.sync(flags: .barrier) {
i = newValue
}
}
}
}
in the case of class property, you can use a concurrent private queue and read from different thread concurrently and dispatch write asynchronously with a barrier
import Dispatch
class S {
private var i: Int = 0 {
didSet {
print("someone did set new value:", i)
}
}
private let queue = DispatchQueue(label: "private", qos: .userInteractive, attributes: .concurrent) // high priority
var value: Int {
get {
return queue.sync {
return i
}
}
set {
if newValue == value {
return
}
queue.async(flags: .barrier) { [unowned self] in
self.i = newValue
}
}
}
}