What is the Swift equivalent to Objective-C's "@synchronized"?
You can use GCD. It is a little more verbose than @synchronized
, but works as a replacement:
let serialQueue = DispatchQueue(label: "com.test.mySerialQueue")serialQueue.sync { // code}
I was looking for this myself and came to the conclusion there's no native construct inside of swift for this yet.
I did make up this small helper function based on some of the code I've seen from Matt Bridges and others.
func synced(_ lock: Any, closure: () -> ()) { objc_sync_enter(lock) closure() objc_sync_exit(lock)}
Usage is pretty straight forward
synced(self) { println("This is a synchronized closure")}
There is one problem I've found with this. Passing in an array as the lock argument seems to cause a very obtuse compiler error at this point. Otherwise though it seems to work as desired.
Bitcast requires both operands to be pointer or neither %26 = bitcast i64 %25 to %objc_object*, !dbg !378LLVM ERROR: Broken function found, compilation aborted!
I like and use many of the answers here, so I'd choose whichever works best for you. That said, the method I prefer when I need something like objective-c's @synchronized
uses the defer
statement introduced in swift 2.
{ objc_sync_enter(lock) defer { objc_sync_exit(lock) } // // code of critical section goes here //} // <-- lock released when this block is exited
The nice thing about this method, is that your critical section can exit the containing block in any fashion desired (e.g., return
, break
, continue
, throw
), and "the statements within the defer statement are executed no matter how program control is transferred."1