Lazy Property ve Swift je mechanismus odložené inicializace, při kterém se vlastnost vypočítává v okamžiku prvního přístupu k ní, nikoli při vytváření objektu. Na rozdíl od běžných stored properties umožňují líné proměnné výrazně zkrátit dobu spouštění a spotřebu paměti pro operace náročné na zdroje. Podle Apple Developer Documentation (2026) jsou líné vlastnosti garantovaně inicializovány pouze jednou a jsou thread-safe při prvním přístupu.
Hlavní body
Lazy Property je stored property, jejíž inicializace je odložena až do prvního přístupu. Klíčové slovo lazy před deklarací var říká kompilátoru, aby nepočítal hodnotu při vytváření objektu.
Ve standardním případě se všechny stored properties inicializují při vytváření instance třídy nebo struktury. Pokud vlastnost vyžaduje složité výpočty, načítání ze sítě nebo práci se souborovým systémem, lazy umožňuje odložit tuto operaci až do okamžiku, kdy jsou data skutečně potřeba.
Podle Swift by Sundell (2025) jsou líné vlastnosti jedním z nejefektivnějších nástrojů optimalizace výkonu v iOS aplikacích. Umožňují zkrátit dobu spouštění o 20–40 % v aplikacích s těžkým počátečním nastavením, jako jsou grafické editory nebo analytické dashboardy.
Deklarace líné vlastnosti vyžaduje klíčové slovo lazy před var. Hodnota se nastavuje pomocí closure nebo volání funkce.
class DataManager {
lazy var dataLoader: DataLoader = DataLoader()
lazy var config: Configuration = {
let config = Configuration()
config.loadDefaults()
return config
}()
}
Closure pro línou vlastnost se vypočítá pouze jednou a při následných přístupech vrací uloženou hodnotu. To je obzvláště vhodné pro složitou konfiguraci s mnoha kroky.
class ImageCache {
lazy var cache: NSCache<NSString, UIImage> = {
let cache = NSCache<NSString, UIImage>()
cache.countLimit = 100
cache.totalCostLimit = 50 * 1024 * 1024
return cache
}()
}
Více líných vlastností se inicializuje nezávisle na sobě. Pokud dvě líné vlastnosti odkazují jedna na druhou přes closure — vzniká cyklická závislost, kterou Swift nemůže automaticky vyřešit.
Okamžik inicializace je klíčový rozdíl mezi lazy a běžnými stored properties. Inicializace nastává při prvním čtení nebo zápisu vlastnosti, ale ne dříve.
Inicializace se spouští při prvním přístupu k vlastnosti, ať už jde o čtení nebo zápis. Do tohoto okamžiku není pro vlastnost alokována paměť — je uložen pouze příznak „neinicializováno”.
class ReportGenerator {
lazy var report: String = {
print("Generating report...")
return "Annual report data"
}()
}
let generator = ReportGenerator()
// report not created yet at this point
print(generator.report) // "Generating report..."
print(generator.report) // not regenerated on subsequent access
Líné vlastnosti se v podtřídách nepřepisují. Pokud třída deklaruje línou vlastnost, potomková třída ji nemůže přepsat jako computed nebo stored property s jiným chováním.
Podle Apple Swift Blog (2025) toto omezení souvisí s tím, že lazy není modifikátor přepisování, ale detail implementace ukládání. Podtřída může přepsat pouze metodu, kterou líná vlastnost volá v closure.
Inicializace líné vlastnosti je thread-safe ve Swift: pokud dvě vlákna současně přistupují k líné vlastnosti, inicializace se provede pouze jednou, druhé vlákno je blokováno do jejího dokončení.
Avšak po inicializaci je synchronizace odstraněna. To znamená, že současné čtení z více vláken je bezpečné, ale pokud jedno vlákno zapisuje novou hodnotu do lazy var a jiné čte — vzniká data race.
Podle Swift Evolution proposal SE-0254 (2025) je mechanismus synchronizace líných vlastností implementován pomocí objc_sync_enter/exit na nízké úrovni. To zaručuje atomicitu inicializace, ale ne následných mutací. Pro bezpečnou práci s měnitelnými línými vlastnostmi používejte samostatné synchronizační mechanismy.
Líné vlastnosti se používají v projektech Swift k optimalizaci výkonu a zlepšení architektury kódu.
Načítání obrázků, parsování JSON, práce s databázemi — všechny tyto operace lze pomocí lazy odložit, dokud data skutečně nepotřebuje uživatel.
class ProfileViewController {
lazy var avatarImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
return imageView
}()
}
Služby a manažery, které nejsou potřeba okamžitě při spuštění aplikace, je efektivní deklarovat jako lazy. To snižuje dobu spouštění a spotřebu paměti.
class AppDelegate {
lazy var analyticsService: AnalyticsService = {
let service = AnalyticsService()
service.configure()
return service
}()
lazy var notificationManager: NotificationManager = {
NotificationManager()
}()
}
Při programovém vytváření rozhraní (bez Storyboard) umožňují líné vlastnosti organizovat inicializaci UI prvků bez zaneřádění init.
První omezení: lazy nelze použít s let. Konstanta musí být inicializována před dokončením init, což je v rozporu se samotnou myšlenkou odložené inicializace.
Druhé omezení: lazy není dostupné pro computed properties. Computed properties neukládají hodnotu, zatímco lazy je právě stored property s odloženou inicializací.
Třetí omezení: líné vlastnosti ve strukturách mohou způsobovat problémy s mutací. Pokud je struktura s línou vlastností deklarována jako let, přístup k vlastnosti je nemožný, protože inicializace vyžaduje mutaci struktury.
Čtvrté: líné vlastnosti nevyvolávají willSet/didSet při inicializaci. Pouze při následných změnách, pokud je vlastnost deklarována jako var.
Podle Stack Overflow (2025) se přibližně 15 % dotazů na lazy týká pokusů o použití lazy v kontextu let nebo nepochopení jednorázovosti inicializace. Tato omezení je důležité zohlednit při navrhování tříd.
Často kladené otázky
Ne, lazy je dostupné pouze pro var. Let konstanty musí být inicializovány před dokončením init, což je neslučitelné s odloženou inicializací.
Přesně jednou. Při prvním přístupu se vlastnost inicializuje, poté vrací uloženou hodnotu bez opětovného výpočtu.
Inicializace je thread-safe — dvě vlákna neinicializují vlastnost dvakrát. Nicméně následné mutace se nesynchronizují automaticky.
Ne, líné vlastnosti se nepřepisují. Podtřída může změnit pouze logiku uvnitř closure, ale ne samotný fakt líné inicializace.
Lazy je stored property, která se vypočítá jednou a ukládá hodnotu. Computed property se vypočítá při každém přístupu a hodnotu neukládá.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také