Właściwości lazy w Swift są obliczane tylko przy pierwszym odniesieniu do nich. Często stosuje się je dla obiektów, które są drogie pod względem zasobów (np. ciężkie obliczenia, pobieranie z sieci), które nie są potrzebne od razu. Deklaruje się je za pomocą słowa kluczowego lazy:
class DataFetcher { lazy var data: Data = self.loadData() func loadData() -> Data { /* … */ } }
Cechy i szczegóły:
lazy mogą być stosowane tylko do zmiennych (var), nie do stałych (let).lazy nie działają, jeśli sama struktura jest immutable.lazy jest cachowana dla każdego egzemplarza z osobna.Pytanie: "Czy wartość właściwości lazy jest tworzona podczas inicjalizacji egzemplarza klasy?"
Odpowiedź: Nie, wartość jest obliczana tylko przy pierwszym dostępie do właściwości, a nie podczas inicjalizacji.
class Expensive { init() { print("init") } } class Example { lazy var heavy = Expensive() } let foo = Example() // nic nie wypisuje _ = foo.heavy // teraz "init"
Historia
W projekcie na dwie platformy używano leniwego tablicy (lazy var) do przechowywania cache’u obrazów. Przy jednoczesnym dostępie z kilku wątków występowały wyścigi, owinęli lazy var mutexami — ale zapomnieli o lazy, co doprowadziło do awarii aplikacji.
Historia
Młodszy programista próbował zadeklarować lazy let, aby zcache’ować ciężkie obliczenie. Kod nie kompilował się, ponieważ lazy jest dozwolone tylko dla var: trzeba było przemyśleć architekturę.
Historia
Programista deklarował właściwość lazy z przechwyceniem self wewnątrz closure podczas inicjalizacji. Doprowadziło to do cyklicznego odwołania — obiekt nie został zdeinicjalizowany nawet po odejściu ze wszystkich ekranów.