Ответ
Проблема: Стандартные массивы Swift (Array) не являются потокобезопасными. Одновременная модификация из нескольких потоков без синхронизации приводит к состоянию гонки (race condition).
Последствия:
- Повреждение данных (Data Race): Внутренняя структура массива может быть нарушена, что приводит к неопределенному поведению, включая сбои приложения.
- Потеря обновлений: Записи, сделанные одним потоком, могут быть перезаписаны другим.
- Некорректное состояние: Массив может содержать неожиданные или противоречивые значения.
Решение — синхронизация доступа:
-
Использование
DispatchQueue(барьер или серийная очередь):let syncQueue = DispatchQueue(label: "com.example.sync", attributes: .concurrent) var threadSafeArray = [Int]() // Запись с барьером (эксклюзивный доступ) syncQueue.async(flags: .barrier) { threadSafeArray.append(42) } // Чтение (параллельный доступ) syncQueue.sync { print(threadSafeArray.last) } -
Использование
NSLockилиpthread_mutex_t:let lock = NSLock() var array = [Int]() lock.lock() array.append(42) lock.unlock() -
Использование
Actor(Swift 5.5+):actor SafeArrayContainer { private var array = [Int]() func append(_ value: Int) { array.append(value) } func getLast() -> Int? { return array.last } } // Использование let container = SafeArrayContainer() Task { await container.append(42) }
Альтернативы: Использование специализированных потокобезопасных структур данных (например, из NSCache для кэширования или реализация собственной обертки).