Lazy Property in Swift is een mechanisme van uitgestelde initialisatie waarbij de eigenschap wordt berekend op het moment van de eerste aanroep, niet bij het aanmaken van het object. In tegenstelling tot gewone stored properties, stellen luie variabelen in staat om de opstarttijd en het geheugengebruik voor resource-intensieve bewerkingen aanzienlijk te verminderen. Volgens Apple Developer Documentation (2026) worden luie eigenschappen gegarandeerd slechts één keer geïnitialiseerd en zijn ze thread-safe bij de eerste toegang.
Belangrijkste punten
Lazy Property is een stored property waarvan de initialisatie wordt uitgesteld tot de eerste aanroep. Het sleutelwoord lazy voor de declaratie van var geeft de compiler aan de waarde niet te berekenen bij het aanmaken van het object.
In het standaardgeval worden alle stored properties geïnitialiseerd bij het aanmaken van een instantie van een klasse of structuur. Als een eigenschap complexe berekeningen, laden via het netwerk of werken met het bestandssysteem vereist, stelt lazy in staat deze bewerking uit te stellen tot het moment waarop de gegevens echt nodig zijn.
Volgens Swift by Sundell (2025) zijn luie eigenschappen een van de meest effectieve optimalisatie-instrumenten in iOS-applicaties. Ze stellen in staat de opstarttijd met 20–40% te verkorten in applicaties met zware initiële configuratie, zoals grafische editors of analytische dashboards.
Declaratie van een luie eigenschap vereist het sleutelwoord lazy voor var. De waarde wordt ingesteld via een closure of functieaanroep.
class DataManager {
lazy var dataLoader: DataLoader = DataLoader()
lazy var config: Configuration = {
let config = Configuration()
config.loadDefaults()
return config
}()
}
De closure voor een luie eigenschap wordt slechts één keer berekend en retourneert de opgeslagen waarde bij volgende aanroepen. Dit is vooral handig voor complexe configuratie met meerdere stappen.
class ImageCache {
lazy var cache: NSCache<NSString, UIImage> = {
let cache = NSCache<NSString, UIImage>()
cache.countLimit = 100
cache.totalCostLimit = 50 * 1024 * 1024
return cache
}()
}
Meerdere luie eigenschappen worden onafhankelijk van elkaar geïnitialiseerd. Als twee luie eigenschappen via closures naar elkaar verwijzen — ontstaat er een cyclische afhankelijkheid die Swift niet automatisch kan oplossen.
Het moment van initialisatie is het belangrijkste verschil tussen lazy en gewone stored properties. Initialisatie vindt plaats bij de eerste lees- of schrijfbewerking van de eigenschap, maar niet eerder.
Initialisatie wordt gestart bij de eerste aanroep van de eigenschap, of het nu lezen of schrijven is. Tot dit moment wordt er geen geheugen voor de eigenschap toegewezen — alleen een vlag 'niet geïnitialiseerd' wordt opgeslagen.
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
Luie eigenschappen worden niet overschreven in subklassen. Als een klasse een luie eigenschap declareert, kan de subklasse deze niet overschrijven als computed of stored property met ander gedrag.
Volgens Apple Swift Blog (2025) is deze beperking te wijten aan het feit dat lazy geen overschrijvingsmodificator is, maar een implementatiedetail van de opslag. Een subklasse kan alleen de methode overschrijven die de luie eigenschap in de closure aanroept.
Initialisatie van een luie eigenschap is thread-safe in Swift: als twee threads tegelijkertijd een luie eigenschap benaderen, wordt de initialisatie slechts één keer uitgevoerd, de tweede thread wordt geblokkeerd tot de voltooiing ervan.
Echter, na initialisatie wordt de synchronisatie opgeheven. Dit betekent dat gelijktijdig lezen uit meerdere threads veilig is, maar als één thread een nieuwe waarde in lazy var schrijft en een andere leest — ontstaat er een data race.
Volgens Swift Evolution proposal SE-0254 (2025) is het synchronisatiemechanisme van luie eigenschappen geïmplementeerd via objc_sync_enter/exit op laag niveau. Dit garandeert atomiciteit van initialisatie, maar niet van volgende mutaties. Gebruik voor veilig werken met mutable lazy eigenschappen aparte synchronisatiemechanismen.
Luie eigenschappen worden gebruikt in Swift-projecten voor prestatieoptimalisatie en verbetering van de codearchitectuur.
Laden van afbeeldingen, parsen van JSON, werken met databases — al deze bewerkingen kunnen met lazy worden uitgesteld tot de gegevens echt door de gebruiker nodig zijn.
class ProfileViewController {
lazy var avatarImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
return imageView
}()
}
Diensten en managers die niet direct bij het opstarten van de applicatie nodig zijn, kunnen efficiënt als lazy worden gedeclareerd. Dit vermindert de opstarttijd en het geheugengebruik.
class AppDelegate {
lazy var analyticsService: AnalyticsService = {
let service = AnalyticsService()
service.configure()
return service
}()
lazy var notificationManager: NotificationManager = {
NotificationManager()
}()
}
Bij het programmatisch creëren van de interface (zonder Storyboard) stellen luie eigenschappen in staat de initialisatie van UI-elementen te organiseren zonder de init te vervuilen.
Eerste beperking: lazy kan niet worden gebruikt met let. Een constante moet vóór de voltooiing van init worden geïnitialiseerd, wat in tegenspraak is met het idee van uitgestelde initialisatie.
Tweede beperking: lazy is niet beschikbaar voor computed properties. Computed properties slaan geen waarde op, terwijl lazy precies een stored property met uitgestelde initialisatie is.
Derde beperking: luie eigenschappen in structuren kunnen problemen veroorzaken met mutatie. Als een structuur met een luie eigenschap als let wordt gedeclareerd, is toegang tot de eigenschap onmogelijk omdat initialisatie mutatie van de structuur vereist.
Vierde: luie eigenschappen roepen willSet/didSet niet aan bij initialisatie. Alleen bij volgende wijzigingen, als de eigenschap als var is gedeclareerd.
Volgens Stack Overflow (2025) heeft ongeveer 15% van de vragen over lazy betrekking op pogingen om lazy in let-context te gebruiken of het niet begrijpen van de eenmaligheid van initialisatie. Deze beperkingen zijn belangrijk om in overweging te nemen bij het ontwerpen van klassen.
Veelgestelde vragen
Nee, lazy is alleen beschikbaar voor var. Let-constanten moeten vóór de voltooiing van init worden geïnitialiseerd, wat onverenigbaar is met uitgestelde initialisatie.
Precies één keer. Bij de eerste aanroep wordt de eigenschap geïnitialiseerd, waarna het de opgeslagen waarde retourneert zonder herberekening.
Initialisatie is thread-safe — twee threads initialiseren de eigenschap niet twee keer. Echter, volgende mutaties worden niet automatisch gesynchroniseerd.
Nee, luie eigenschappen worden niet overschreven. Een subklasse kan alleen de logica binnen de closure wijzigen, maar niet het feit van luie initialisatie zelf.
Lazy is een stored property die eenmaal wordt berekend en de waarde opslaat. Computed property wordt bij elke aanroep berekend en slaat geen waarde op.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook