value += 1 } ... } class Counter{ private var value = 0 private let queue = DispatchQueue() public func add(){ queue.async{ value += 1 } } ... } class Counter{ private var value = 0 private let queue = DispatchQueue() public func add(){ queue.async{ value += 1 } } public func addTwice() { queue.async{ value += 2 } } public func add(from:TimesProvider){ queue.async{ value += from.value } } Traditional thread-safety API
class Counter{ private var value = 0 private let queue = DispatchQueue() public func add(){ queue.async{ value += 1 } } public func addTwice() { queue.async{ value += 2 } } public func add(from:TimesProvider){ queue.async{ value += from.value } } } External dependencies (e.g. arguments) may be thread-unsafe #2 Dependencies thread-safety Pitfalls Traditional way // nonatomic
class CounterActor { func send(_ message:CounterMessage){…} } enum CounterMessage { case add(Int) case subtract(Int) } counterActor.send(.add(1)) Actor Swift
Counter{ private var value = 0 private let otherActor:OtherActor actor func add(){ // queue.async{ value += 1 //} } actor func addTwice() { // queue.async{ value += 2 //} } public func add(from:TimesProvider){ value += 2 } } Compiler’s addition