One of the cool features of Swift are property observers, perhaps better known as the willSet and didSet. Everyone programming in Swift must have used them. Some people more than others. And some people might use them a little bit too much, changing many of them together (me sometimes included). But it’s not always completely obvious when they are called. Especially when dealing with struct, because structs can be a bit odd. Let’s dive into some situations and see what happens.


The most obvious situation in which didSet (and willSet) gets called is by simply assigning a variable. Imagine the following struct:

And some other code, like a view controller that is using it in a variable with a property observer.

As you would expect, the code in didSet will be executed when the view did load and the following is printed to the console:


This one is also pretty clear and you probably already know about it: property observers are not executed then the variable is assigned during initialization.

This doesn’t print anything to the console. Also if you would assign person in the init function instead the willSet will not get called.

Modifying structs

A thing less known is that property observers are also executed when you change the member values of structs without (re)assigning the entire struct. The following sample illustrates this.

In this sample we never reassign the person in our viewDidLoad function but by changing the name and age, the willSet still gets executed twice and we get as output:

Mutating functions

The same that applies to changing values of a struct also applies to mutating struct functions. Calling such a function always results in the property observers being called once. It does not matter if you replace the entire struct (by assigning self), change multiple member values or don’t change anything at all.

Here we added a mutating function that increments the age as long as the age is lower than 100.

Our willSet is called 4 times, even though the last two times nothing has changed.

Changes inside property observers

It is also possible to make changes to the variable inside its own property observers. You can reassign the entire variable, change its values or call mutating functions on it. When you do that from inside a property observer, the property observers do not trigger since that would most likely cause an endless loop. Keep in mind that changing something in willSet will be without effect since your change will be overwritten by that value that was being set originally (this gives a nice warning in Xcode as well).

Why it matters

So why does all this matter so much you might think. Well, you might have to rethink what kind of logic you put into your property observers and which you put outside. And all this applies to Arrays and Dictionaries as well, because they are also structs. Let’s say you have an array of numbers that can change and each time it changes you want to update your UI. But you also want to sort the numbers. The following code might look fine to you at first:

Every time numbers changes, the UI will be updated. But since sortInPlace will also trigger the property observer, the UI gets updated twice:

So we should really put sortInPlace inside willSet right before we call updateUI.