@synchronized
By examining the code (ADC registration required) that implements
objc_sync_enter
andobc_sync_exit
, we can see that on every@synchronized(foo)
block, we are actually paying for 3 lock/unlock sequences.objc_sync_enter
callsid2data
, which is responsible for getting the lock associated withfoo
, and then locks it.objc_sync_exit
also callsid2data
to get the lock associated withfoo
, and then unlocks it. And,id2data
must lock/unlock its own internal data structures so that it can safely get the lock associated withfoo
, so we pay for that on each call as well.
Plus the overhead of entering an exception handling block, which is currently expensive in Objective-C.
Update: two faster versions. The first takes advantage of a guarantee that (Objective-)C++ makes, and the second uses swizzling to replace the method with one that isn’t synchronized once the initial race condition is over.