Property observers in Swift maken het mogelijk om te reageren op wijzigingen in de waarde van een eigenschap. Dit concept werd geïntroduceerd met Swift om de transparantie van gegevensverandering te vergroten en om de logica voor wijzigingen te automatiseren.
Achtergrond:
Voor Swift werd een dergelijk gedrag vaak handmatig geïmplementeerd via setters of speciale methoden. In Swift zijn observers een standaard functie van de taal geworden.
Probleem:
Het is belangrijk voor de ontwikkelaar om het moment van een eigenschapswijziging te kunnen opvangen — bijvoorbeeld om de UI bij te werken of om gegevens te valideren. Zonder observers zou de code omvangrijker en moeilijker leesbaar worden.
Oplossing:
In Swift zijn er twee hoofd-observers beschikbaar:
willSet wordt aangeroepen vóór de waarde wijzigingdidSet wordt aangeroepen na de toewijzing van een nieuwe waardeObservers kunnen worden toegevoegd aan stored properties, behalve lazy properties en computed properties.
Codevoorbeeld:
class Temperature { var celsius: Double { willSet { print("Binnenkort zal de waarde zijn", newValue) } didSet { print("De waarde was:", oldValue, ", en is nu:", celsius) } } init(celsius: Double) { self.celsius = celsius } } let temp = Temperature(celsius: 22) temp.celsius = 28 // Zal willSet en didSet weergeven
Belangrijke kenmerken:
Kun je observers toevoegen aan computed properties?
Nee, aan computed properties kunnen geen willSet en didSet worden toegevoegd, omdat ze al hun eigen getter en setter hebben. Het gebruik van willSet/didSet is alleen relevant voor stored properties.
Worden de observers aangeroepen bij het wijzigen van een eigenschap binnen de initialisator?
Nee, property observers worden niet aangeroepen tijdens de initialisatie (init). Ze worden alleen geactiveerd bij het wijzigen van de waarde na het voltooien van init.
Wat gebeurt er als je de huidige waarde aan zichzelf toewijst, bijvoorbeeld x = x?
De observers worden toch aangeroepen, zelfs als de waarde van de eigenschap niet is veranderd! Dit kan leiden tot ongewenst gedrag — wees voorzichtig.
var value: Int = 0 { didSet { print("didSet wordt altijd aangeroepen!") } } value = value // didSet wordt aangeroepen
Een ontwikkelaar implementeerde een interface-update in didSet, maar controleerde niet op waarde wijziging. De UI werd bijgewerkt, zelfs bij "lege" toewijzing, wat de prestaties verlaagde.
Voordelen:
Nadelen:
In didSet werd gecontroleerd op gelijkenis tussen oude en nieuwe waarde. De interface-update vond alleen plaats als de waarde daadwerkelijk was gewijzigd.
Voordelen:
Nadelen: