Если вам просто нужно защитить критическую часть кода, почему бы не использовать директиву Objective-C @synchronized? Конечно, использование NSLock также будет работать, но вам нужно явно управлять экземпляром NSLock. Из документации:
Objective-C поддерживает многопоточность в приложениях. Это означает, что два потока могут пытаться изменить один и тот же объект одновременно, что может вызвать серьезные проблемы в программе. Чтобы защитить разделы кода от одновременного выполнения несколькими потоками, Objective-C предоставляет директиву @synchronized ().
Директива @synchronized () блокирует часть кода для использования одним потоком. Другие потоки блокируются, пока поток не выйдет из защищенного кода; то есть, когда выполнение продолжается после последнего оператора в блоке @synchronized ().
Директива @synchronized () принимает в качестве единственного аргумента любой объект Objective-C, включая self. Этот объект известен как семафор взаимного исключения или мьютекс. Это позволяет потоку заблокировать часть кода, чтобы предотвратить его использование другими потоками. Вы должны использовать отдельные семафоры для защиты различных критических разделов программы. Прежде чем приложение станет многопоточным, безопаснее всего создавать все объекты взаимного исключения, чтобы избежать условий гонки.
В листинге 12-1 показан пример кода, который использует self в качестве мьютекса для синхронизации доступа к методам экземпляра текущего объекта. Вы можете использовать аналогичный подход для синхронизации методов класса связанного класса, используя объект Class вместо self. В последнем случае, конечно, только одному потоку одновременно разрешено выполнять метод класса, поскольку существует только один объект класса, который является общим для всех вызывающих.
Листинг 12-1. Блокировка метода с помощью self
- (void)criticalMethod
{
@synchronized(self) {
// Critical code.
...
}
}