Ответ
Оба инструмента синхронизации, но решают разные задачи.
NSLock (Мьютекс)
- Назначение: Бинарная блокировка для защиты критической секции (участка кода, который может выполняться только одним потоком одновременно).
- Принцип:
lock()/unlock(). Поток, захвативший блокировку, должен её и освободить. - Особенности: Нельзя вызвать
unlock()из другого потока. Естьtry()для неблокирующей попытки.let lock = NSLock() var sharedArray = [Int]()
func addElement(_ element: Int) { lock.lock() sharedArray.append(element) // Безопасный доступ lock.unlock() }
**DispatchSemaphore (Семафор)**
* **Назначение:** Контролирует доступ к ресурсу (или группу ресурсов) на основе **счетчика**. Может использоваться для синхронизации и ожидания событий.
* **Принцип:** `wait()` уменьшает счетчик. Если счетчик < 0, поток блокируется. `signal()` увеличивает счетчик и разблокирует ожидающий поток.
* **Особенности:** Позволяет ограничить количество одновременных потоков (не только одним).
```swift
// Пример 1: Ограничение параллельных задач (макс. 3)
let semaphore = DispatchSemaphore(value: 3)
for i in 1...10 {
DispatchQueue.global().async {
semaphore.wait() // Вход. Если счетчик = 0, ждем.
downloadLargeFile(id: i)
semaphore.signal() // Выход
}
}
// Пример 2: Ожидание завершения асинхронной задачи
let finishSemaphore = DispatchSemaphore(value: 0)
networkService.fetchData { result in
// Обработка результата
finishSemaphore.signal() // Сигнализируем о завершении
}
finishSemaphore.wait() // Блокируем текущий поток до получения сигнала
| Ключевые отличия: | NSLock | DispatchSemaphore | |
|---|---|---|---|
| Тип | Бинарный мьютекс | Счетный семафор | |
| Основная цель | Защита критической секции | Ограничение параллелизма, ожидание событий | |
| Гибкость | Один поток на ресурс | N потоков на ресурс |