Ответ
Потокобезопасность гарантирует корректность данных при одновременном доступе из нескольких потоков. Вот основные подходы в Swift:
1. Использование DispatchQueue с барьером (barrier)
Наиболее распространённый и гибкий способ для чтения/записи.
class ThreadSafeContainer<T> {
private var value: T
private let queue = DispatchQueue(label: "com.example.threadsafe", attributes: .concurrent)
init(value: T) { self.value = value }
var currentValue: T {
get {
return queue.sync { value } // Конкурентное чтение
}
set {
queue.async(flags: .barrier) { // Эксклюзивная запись
self.value = newValue
}
}
}
}
2. Использование мьютексов (Mutex) Более низкоуровневый, но эффективный контроль.
import os
class ThreadSafeValue<T> {
private var value: T
private let lock = os_unfair_lock()
init(value: T) { self.value = value }
func update(_ block: (inout T) -> Void) {
os_unfair_lock_lock(&lock)
defer { os_unfair_lock_unlock(&lock) }
block(&value)
}
func read() -> T {
os_unfair_lock_lock(&lock)
defer { os_unfair_lock_unlock(&lock) }
return value
}
}
3. Property Wrapper (обёртка свойства) Удобный современный способ инкапсулировать логику синхронизации.
@propertyWrapper
struct ThreadSafe<T> {
private var value: T
private let lock = NSLock()
init(wrappedValue: T) {
self.value = wrappedValue
}
var wrappedValue: T {
get {
lock.lock()
defer { lock.unlock() }
return value
}
set {
lock.lock()
defer { lock.unlock() }
value = newValue
}
}
}
// Использование
class Model {
@ThreadSafe var counter: Int = 0
}
Важно: Потокобезопасность переменной не гарантирует потокобезопасность всей системы. Необходимо анализировать все точки доступа к общим данным.