Property observers provide a way to respond to changes in the values of properties of a class, struct or enumeration. They enable you to run some custom code before or after the value of a property changes. Property observers are available for stored and computed properties. Let's take a look at how property observers are used in Swift with the following code snippet:
class Account {
var balance: Double {
willSet(newBalance) {
print("About to change balance from \(balance) to \(newBalance)")
}
didSet {
print("Balance changed from \(oldValue) to \(balance)")
}
}
init(balance: Double) {
self.balance = balance
}
}
var myAccount = Account(balance: 1000)
myAccount.balance = 2000 // Output: "About to change balance from 1000.0 to 2000.0" and "Balance changed from 1000.0 to 2000.0"
Here, we have defined a class named `Account` which has a stored property named `balance`. The `willSet` block is executed just before the stored property's value is set to the new value. In this case, it is used to print a message that describes the old and new values of the `balance` property. The `didSet` block is executed just after the stored property's value has been set with the new value. In this case, it is used to print a message that describes the old and new values of the `balance` property.
We can also use these property observers in computed properties, which allows us to execute some custom code whenever their values change.
struct Temperature {
var celcius: Double {
willSet {
print("About to change temperature from \(celcius)℃ to \(newValue)℃")
}
didSet {
if celcius > oldValue {
print("Temperature has increased by \(celcius - oldValue)℃")
} else if celcius < oldValue {
print("Temperature has decreased by \(oldValue - celcius)℃")
}
}
}
init(celcius: Double) {
self.celcius = celcius
}
}
var currentTemperature = Temperature(celcius: 20.0)
currentTemperature.celcius = 25.0
// Output: "About to change temperature from 20.0℃ to 25.0℃" and "Temperature has increased by 5.0℃"
In this example, we have a computed property named `celcius` in our struct `Temperature`. We have implemented the `willSet` and `didSet` property observers to print a message that describes the old and new temperature values. The `didSet` block is also used to print a message that describes whether the temperature has increased or decreased and by how much amount.