Скорее всего, вы использовали или, по крайней мере, видели ранее использованное ключевое слово lazy
. Однако вы никогда не задумывались о том, каковы истинные возможности ленивого хранимого свойства. Я хочу рассказать вам о том, что такое ленивые свойства, почему они существуют и как вы можете ими воспользоваться.
Первоначально это сообщение было опубликовано 1 неделей ранее на kristofk.com.
Земляные работы
Начальное значение лениво хранимых свойств не вычисляется и не присваивается до тех пор, пока вы не вызовете это свойство. Вы можете думать об этом как о свойстве по требованию, оно не существует в памяти, пока вы его не вызовете.
Ленивое свойство всегда должно быть переменной, поскольку константы всегда должны иметь начальное значение при инициализации экземпляра.
⚠ Ленивые хранимые свойства не являются потокобезопасными!
Если к свойству, отмеченному модификатором _2, одновременно обращаются несколько потоков, и свойство еще не было инициализировано, нет гарантии, что свойство будет инициализирован только один раз.
Когда вы используете ленивое хранимое свойство?
- Когда свойство зависит от внешнего источника и значение может быть неизвестно до завершения инициализации (асинхронные вызовы, такие как веб-запрос).
- Если начальное значение свойства требует дорогостоящей в вычислительном отношении настройки, которую не следует выполнять до тех пор, пока значение не понадобится
- Чтобы избежать необязательных опций, также известных как необязательные опции
- Держите инициализаторы в чистоте, откладывая некоторые настройки до тех пор, пока позже в жизненном цикле объекта
Самый простой способ реализовать ленивое хранимое свойство — поместить ключевое слово lazy перед переменной со значением по умолчанию. Это означает, что свойство не будет инициализировано в процессе инициализации типа. Начальное значение будет присвоено только при вызове свойства.
Еще один способ инициализировать ленивое свойство — использовать метод. Это полезно, если вы хотите разделить свойство и инициализацию или если у вас длинная и сложная инициализация. Для этого вам нужно создать метод инициализации и вызвать его для свойства.
В этом примере я использовал числа Фибоначчи, так как они могут требовать значительных вычислительных ресурсов. Я сделал этот пример неоптимизированным, чтобы подчеркнуть, что это не так, как вы бы реализовали это в реальной жизни.
Если вы похожи на меня и вам нравится компактность, когда она не ставит под угрозу читабельность, вы можете переместить весь код, определенный в методе инициализации, в автоматически выполняющееся замыкание.
Есть еще один способ присвоить начальное значение ленивому свойству — использовать методы типов. Этот метод основан на принципе единой ответственности и разделении типов. Это самый утомительный из всех, и я рекомендую его только в том случае, если вы действительно найдете ему хорошее применение.
Например, в моем примере у меня есть 2 класса. Один посвящен числам Фибоначчи, а другой — общему математическому классу.
Вывод
Ленивые сохраненные свойства могут быть очень полезны для оптимизации использования ОЗУ и ЦП и обеспечения удобочитаемости нашей базы кода.
Нет никаких признаков разницы в производительности между любым из вышеперечисленных методов инициализации свойства.
Если у вас есть какие-либо вопросы, вы можете задать их мне в комментариях или в Твиттере @kristofkocsis.
Если вы хотите узнать больше о ленивых хранимых свойствах, я рекомендую следующие ресурсы:
- Страница официальной документации Apple
- Использование ленивых свойств в Swift — Swift by Sundell
- Что такое ленивые переменные? — Взлом со Swift
Первоначально опубликовано на сайте kristofk.com 14 марта 2018 г.