Skip to content

Instantly share code, notes, and snippets.

@zhihuitang
Created February 8, 2020 21:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zhihuitang/29eb493edbfc404ca3016e3485c1f703 to your computer and use it in GitHub Desktop.
Save zhihuitang/29eb493edbfc404ca3016e3485c1f703 to your computer and use it in GitHub Desktop.
// https://www.vadimbulavin.com/swift-atomic-properties-with-property-wrappers/
/*
Although get and set are individually atomic, the combination of both is not.
Incrementing x is not atomic, since it first calls get and then set:
*/
@propertyWrapper
struct Atomic<Value> {
private let queue = DispatchQueue(label: "com.vadimbulavin.atomic")
private var value: Value
init(wrappedValue: Value) {
self.value = wrappedValue
}
var wrappedValue: Value {
get {
return queue.sync { value }
}
set {
queue.sync { value = newValue }
}
}
func mutate(_ mutation: (inout Value) -> Void) {
queue.sync { mutation(&value) }
}
}
struct MyStruct {
@Atomic var x = 0
}
// Verison 2
/*
When we update a value in a collection (Array, Set and Dictionary),
both get and set are called. Make sure to use the mutate() method in such cases:
*/
@propertyWrapper
class Atomic<T> {
private let queue = DispatchQueue(label: "com.vadimbulavin.atomic")
var projectedValue: Atomic<T> { return self }
var value: T
init(wrappedValue: T) {
self.value = wrappedValue
}
var wrappedValue: T {
get {
print("wrappedValue get \(value)")
return queue.sync { value }
}
set {
print("wrappedValue set \(newValue) -> \(value)")
queue.sync { value = newValue }
}
}
func mutate(_ mutation: (inout T) -> Void) {
queue.sync { mutation(&value) }
}
func help() {
print("help")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment