В Swift существует несколько способов защиты данных от гонки (data races): NSLock, DispatchSemaphore, последовательные очереди (DispatchQueue). Но на WWDC24 компания Apple представила новый Synchronization Framework, включающий современный Mutex – стандартизированную блокировку взаимного исключения.
🤔 В чем разница между Lock и Mutex?
🔸 Lock: общее название механизмов синхронизации (например, NSLock, os_unfair_lock).
🔸 Mutex: частный случай блокировки, гарантирующий, что только один поток может владеть ресурсом в данный момент.
✅ Ключевая особенность Mutex:
🔹 Строгое владение – разблокировать может только тот поток, который заблокировал.
🔹 Поддержка Sendable, что делает его удобным для Swift Concurrency.
♣️ Пример использования.
Пример защиты счетчика:
final class Counter {
private let count = Mutex<Int>(0) // Обернули значение в Mutex
var currentCount: Int {
count.withLock { $0 } // Безопасное чтение
}
func increment() {
count.withLock { $0 += 1 } // Атомарная операция
}
func decrement() throws {
try count.withLock {
guard $0 > 0 else { throw Error.reachedZero }
$0 -= 1
}
}
}
🆚 Mutex vs Actor.
🔸 Actor: идеален для асинхронного доступа, но требует await.
🔸 Mutex: синхронный, подходит для legacy кода или когда нельзя использовать async/await.
⚠️ Когда выбирать Mutex?
🔸 Нужна мгновенная синхронная блокировка.
🔸 Работа с не Sendable типами (например NSBezierPath).
🔸 Интеграция с кодом, не поддерживающим Concurrency.
💡 Важно:
🔹 Доступен с iOS 18 и macOS 15.
🔹 Не заменяет Actor, а дополняет инструментарий для работы с многопоточностью.
Mutex из Synchronization Framework – это современный, безопасный и эффективный способ защиты данных в Swift.
➡️ Подписаться на канал
Мобильный трудоголик