Property Observers didSet and willSet in Swift 4

Published Jan 20, 2018
Property Observers didSet and willSet in Swift 4

In this article, we will look into swift property observers. According to Apple’s documentation:

Property observers observe and respond to changes in a property’s value. Property observers are called every time a property’s value is set, even if the new value is the same as the property’s current value .

Lets have a look at the code snippet below to help us have a better understanding of how property observers willSet and didSet works.

import UIKit

struct Person {
    var name: String
    var age: Int
}

class ViewController: UIViewController {

    var person: Person? {
        didSet{

            print("Called after setting the new value")
            if let name = person?.name {
                print("New name is \(name) and old name is \(String(describing: oldValue?.name))")
            }
        }
        willSet(myNewValue) {

            print("Called before setting the new value")
            if let newName = myNewValue?.name {
                print("New name is \(newName)")
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        person = Person(name: "Shem", age: 4)
    }
}

Property observers are declared as a variable and not constants because its only a mutable property that can be tracked by the property observers. Hence property observers are declared with var and not let keyword.

A property with observers on it when declared should have initial value assigned to it. This actually makes the difference between computed property and property observers. Computed properties returns a value computed from other variable or properties and does not store the value in memory. Hence, to place observers on a property, you need to set the property to an initial value of a particular type. This value could be optional type or any other type.

One thing to note is that willSet and didSet will never get called on setting the initial value of the property. It will only get called whenever you set the property by assigning a new value to it. It will always get called even if you assign the same value to it multiple times.

willSet and didSet both have a default parameters newValue and oldValue. You are also free to choose a custom parameter name of your choice as shown in the code above. These parameters are constants, hence you cannot mutate their values. Also note that in didSet, you can access the oldValue parameter and also the property whose value is already set.

Right now, lets explains what happens in the code above. We defined a struct Person with two stored properties name and age. And in placing our observer on the person property of type Person, we made it be of optional type meaning that the initial value of the person property is nil.

When the above code snippet is executed, the code in the viewDidLoad will get executed as can be seen in the screenshot below:
Screen Shot 2018-01-18 at 08.09.49.png

As can be seen from the screenshot above, the code in willSet will get called first before the person property is set. didSet will get called immediately when the person property is already set. That is why we could access the person property in didSet which is not possible in willSet.

From the code also, you can see that I used a custom parameter name in willSet observer; you are free to override the default parameter name with your own custom parameter name if you wish.
One more thing to note about property observers is this: property observers cannot be used on lazy variable because lazy variable get properly initialised and assigned to memory only when they are called in your program. Example is shown below:

lazy var name = "John"
print("My name is \(name)")

The variable name will only get properly initialised and assigned memory only when it has been called in the print statement above.
That defeats the purpose of a property observers because a property with observers on it need to have initial value. This will enable it track changes whenever they is change in value of the property.
The need for property observers arises when you have to keep a track on a property to determine when the value changes in order to perform some logic. So, instead of having some functions that checks the value of the property to perform some action, you can abstract that into the willSet and have it perform some the logic when the value is set to the value you want.

I believe you now have a better understanding of how property observers in swift works after reading through this article. Thanks for reading.

Discover and read more posts from Onyekachi Ezeoke
get started