Ответ
Нет, ленивая инициализация (lazy) в Swift по умолчанию не является потокобезопасной.
Проблема: Если несколько потоков одновременно обратятся к еще не инициализированному lazy-свойству, может произойти состояние гонки (race condition). Это может привести к тому, что инициализирующее замыкание выполнится более одного раза, а конечное значение будет неопределенным.
Пример небезопасного кода:
class DataManager {
// Не потокобезопасное lazy-свойство
lazy var config: [String: String] = {
// Длительная операция...
return ["key": "value"]
}()
}
// Одновременный доступ из нескольких потоков -> риск.
Как обеспечить потокобезопасность?
- Инициализация до параллельного доступа: Гарантировать, что свойство будет инициализировано в главном потоке до его использования в других.
-
Использование мьютекса или очереди: Вручную синхронизировать доступ.
import Dispatch class DataManager { private let queue = DispatchQueue(label: "com.example.sync") private var _config: [String: String]? var config: [String: String] { queue.sync { if let value = _config { return value } let newValue = ["key": "value"] // Инициализация _config = newValue return newValue } } } - Property Wrapper (Swift 5.1+): Создать или использовать готовый обертку (например,
@Atomic), которая инкапсулирует логику синхронизации.
Вывод: При использовании lazy в многопоточной среде необходимо самостоятельно добавлять механизмы синхронизации.