Lazy Property in Swift: wat is het, syntaxis van luie initialisatie

Auteur: IT Sectr Gepubliceerd: 2026-06-20 Leestijd: 10 min

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 — eigenschap wordt geïnitialiseerd bij eerste aanroep, niet bij objectcreatie
  • Alleen var — lazy is verboden voor let, omdat de constante bekend moet zijn voor initialisatie
  • Draadveiligheid — initialisatie van luie eigenschap is gesynchroniseerd, maar herhaalde toegang niet
  • Eenmaligheid — lazy wordt exact één keer berekend, volgende aanroepen retourneren de opgeslagen waarde
  • Optimalisatie — vermindert opstarttijd en geheugengebruik voor zelden gebruikte gegevens

Wat is Lazy Property in Swift?

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.

Syntaxis van luie eigenschap

Declaratie van een luie eigenschap vereist het sleutelwoord lazy voor var. De waarde wordt ingesteld via een closure of functieaanroep.

swift
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.

swift
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.

Wanneer wordt luie eigenschap geïnitialiseerd

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.

Eerste toegang (lezen of schrijven)

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.

swift
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

Gedrag bij overerving

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.

Draadveiligheid van luie eigenschappen

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.

Praktische gebruiksscenario's

Luie eigenschappen worden gebruikt in Swift-projecten voor prestatieoptimalisatie en verbetering van de codearchitectuur.

Zware resources

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.

swift
class ProfileViewController {
    lazy var avatarImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
        return imageView
    }()
}

Singleton-afhankelijkheden

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.

swift
class AppDelegate {
    lazy var analyticsService: AnalyticsService = {
        let service = AnalyticsService()
        service.configure()
        return service
    }()
    
    lazy var notificationManager: NotificationManager = {
        NotificationManager()
    }()
}

UI-componenten met code

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.

Beperkingen en valkuilen

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

Kan lazy worden gebruikt met let?

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.

Hoe vaak wordt een luie eigenschap berekend?

Precies één keer. Bij de eerste aanroep wordt de eigenschap geïnitialiseerd, waarna het de opgeslagen waarde retourneert zonder herberekening.

Is een luie eigenschap veilig in een multi-thread omgeving?

Initialisatie is thread-safe — twee threads initialiseren de eigenschap niet twee keer. Echter, volgende mutaties worden niet automatisch gesynchroniseerd.

Kan een luie eigenschap worden overschreven in een subklasse?

Nee, luie eigenschappen worden niet overschreven. Een subklasse kan alleen de logica binnen de closure wijzigen, maar niet het feit van luie initialisatie zelf.

Wat is het verschil tussen lazy en computed property?

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

  • Lazy Property — mechanisme van uitgestelde initialisatie, uitgevoerd bij eerste toegang
  • Alleen var — lazy is onverenigbaar met let, omdat een constante onmiddellijke initialisatie vereist
  • Eenmaligheid — initialisatie wordt eenmaal uitgevoerd, volgende aanroepen gebruiken de gecachte waarde
  • Draadveiligheid — initialisatie is gesynchroniseerd, maar mutaties na initialisatie vereisen aparte synchronisatie
  • Toepassing — zware resources, UI-componenten, singleton-diensten, configuraties
  • Beperkingen — niet mogelijk in let, computed properties, overschrijving en structuren met let-instanties
  • Optimalisatie — vermindert opstarttijd en geheugengebruik voor zelden gebruikte eigenschappen

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.

Bespreek het project

Lees ook