lazy свойства в Swift вычисляются только при первом обращении к ним. Это часто используется для дорогих по ресурсам объектов (например, тяжёлых вычислений, сетевых загрузок), которые не нужны сразу. Объявляются с помощью ключевого слова lazy:
class DataFetcher { lazy var data: Data = self.loadData() func loadData() -> Data { /* … */ } }
Особенности и тонкости:
lazy свойства допустимы только для переменных (var), не для констант (let).lazy свойства не работают, если сама структура — immutable.lazy-значение кэшируется для каждого экземпляра отдельно.Вопрос: "Создаётся ли значение для lazy property при инициализации экземпляра класса?"
Ответ: Нет, значение вычисляется только при первом доступе к свойству, а не при инициализации.
class Expensive { init() { print("init") } } class Example { lazy var heavy = Expensive() } let foo = Example() // ничего не выводит _ = foo.heavy // теперь "init"
История
В проекте на две платформы использовался ленивый массив (lazy var) для хранения кэша изображений. При одновременном доступе из нескольких потоков возникали гонки, оборачивали lazy var mutex’ами — но забыли про lazy, что привело к краху приложения.
История
Молодой разработчик пытался объявить lazy let, чтобы кэшировать тяжёлое вычисление. Код не компилировался, так как lazy разрешён только для var: пришлось пересматривать архитектуру.
История
Разработчик объявлял lazy property с захватом self внутри closure при инициализации. Это привело к циклической ссылке — объект не деинициализировался даже после ухода со всех экранов.