Eigenschaften mit Beobachtern (Property Observers) in Swift ermöglichen es, auf Änderungen des Wertes einer Eigenschaft zu reagieren. Dieses Konzept wurde zusammen mit Swift eingeführt, um die Transparenz bei der Kontrolle von Datenänderungen zu erhöhen und die Logik bei Änderungen zu automatisieren.
Hintergrund:
Vor Swift wurde ein solches Verhalten häufig manuell über Setter oder spezielle Methoden implementiert. In Swift sind Beobachter als Standardwerkzeug in der Sprache verfügbar.
Problem:
Es ist für Entwickler wichtig, den Moment der Änderung einer Eigenschaft zu erfassen – zum Beispiel zur Aktualisierung der Benutzeroberfläche oder zur Validierung von Daten. Ohne Beobachter würde der Code unhandlicher und weniger lesbar werden.
Lösung:
In Swift stehen zwei Hauptbeobachter zur Verfügung:
willSet wird vor der Änderung des Wertes aufgerufendidSet wird nach der Zuweisung eines neuen Wertes aufgerufenBeobachter können zu stored properties hinzugefügt werden, mit Ausnahme von lazy properties und computed properties.
Beispielcode:
class Temperature { var celsius: Double { willSet { print("Der Wert wird bald gesetzt: ", newValue) } didSet { print("Der alte Wert war:", oldValue, ", der neue Wert ist:", celsius) } } init(celsius: Double) { self.celsius = celsius } } let temp = Temperature(celsius: 22) temp.celsius = 28 // gibt willSet und didSet aus
Wichtige Merkmale:
Kann man Beobachter zu computed properties hinzufügen?
Nein, zu computed properties können keine willSet und didSet hinzugefügt werden, da sie bereits ihren eigenen Getter und Setter haben. Die Verwendung von willSet/didSet ist nur für stored properties relevant.
Werden die Beobachter bei Änderungen einer Eigenschaft innerhalb des Initialisierers aufgerufen?
Nein, Property Observers werden während der Initialisierung (init) nicht aufgerufen. Sie werden nur bei einer Wertänderung nach Abschluss von init aktiviert.
Was passiert, wenn ich einen aktuellen Wert für mich selbst zuweise, zum Beispiel x = x?
Die Beobachter werden dennoch aufgerufen, auch wenn sich der Wert der Eigenschaft nicht geändert hat! Dies kann zu unerwünschten Nebeneffekten führen – seien Sie vorsichtig.
var value: Int = 0 { didSet { print("didSet wird immer aufgerufen!") } } value = value // didSet wird aufgerufen
Der Entwickler hat in didSet die Benutzeroberfläche aktualisiert, aber die Wertänderung nicht kontrolliert. Die UI wurde sogar bei "leeren" Zuweisungen aktualisiert, was die Leistung beeinträchtigte.
Vorteile:
Nachteile:
In didSet wurde überprüft, ob der alte Wert gleich dem neuen Wert ist. Die Aktualisierung der Benutzeroberfläche erfolgte nur, wenn sich der Wert tatsächlich geändert hat.
Vorteile:
Nachteile: