Как работает @synchronized в Objective-C

Язык Objective-C поддерживает синхронизацию для многопоточных приложений. При помощи директивы @synchronized () можно защитить фрагмент кода от одновременного выполнения сразу несколькими потоками.
@synchronized () берёт на вход указатель на объект языка Objective-C (можно использовать для этой цели любой объект, в том числе и self), который играет роль мьютекса (mutex).
При попытке потока начать выполнение защищенного фрагмента проверяется, выполняется ли уже этот фрагмент каким-либо потоком. Если да, то сравниваются объекты, переданные этими потоками в @synchronized ().
Если эти указатели совпадают, то поток, пытающийся войти в защищенный блок, будет приостановлен (suspended) до тех пор, пока первый поток не выйдет из блока. Тогда выполнение второго потока продолжится, и уже он «запрёт» этот блок для всех остальных потоков.
Наличие подобной возможности заметно облегчает жизнь при написании многопоточных приложений, когда необходимо отслеживать попытки одновременного изменения одних и тех же данных сразу несколькими потоками.
- (void) criticalMethod
{
    @synchronized ( self )
    {
         // perform modifications to shared objects
         . . .
    }
}
В качестве мьютекса (т. е. параметра инструкции @synchronized) рекомендуется указывать объект, недоступный извне, поскольку это может привести к взаимной блокировке, если один и тот же объект используется в качестве мьютекса двумя взаимозависимыми потоками. В частности, не рекомендуется @synchronized(self).