What is the difference between willSet
- didSet
, and get
- set
, when working with this inside a property?
From my point of view, both of them can set a value for a property. When, and why, should I use willSet
- didSet
, and when get
- set
?
I know that for willSet
and didSet
, the structure looks like this:
var variable1 : Int = 0 { didSet { println (variable1) } willSet(newValue) { .. } } var variable2: Int { get { return variable2 } set (newValue){ } }
We have two types of property observers: willSet — called before a new value is stored. didSet — called after a new value is stored.
Property Observers. 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. You can add property observers in the following places: Stored properties that you define.
didSet is called right after the data is stored and it has a default constant oldValue which shows the previous value that is overwritten. willSet and didSet cannot be used at computed property since set function has already covered their functionalities and getter only stored property cannot be set actually!
In short, the first is a stored property that is initialized via a closure, with that closure being called only one time, when it is initialized. The second is a computed property whose get block is called every time you reference that property.
When and why should I use willSet/didSet
willSet
is called just before the value is stored.didSet
is called immediately after the new value is stored.Consider your example with outputs:
var variable1 : Int = 0 { didSet{ print("didSet called") } willSet(newValue){ print("willSet called") } } print("we are going to add 3") variable1 = 3 print("we added 3")
Output:
we are going to add 3 willSet called didSet called we added 3
it works like pre/post -condition
On the other hand, you can use get
if you want to add, for example, a read-only property:
var value : Int { get { return 34 } } print(value) value = 2 // error: cannot assign to a get-only property 'value'
@Maxim's answer is for the 1st part of your question.
As for when to use get
and set
: when you want a computed property. This:
var x: Int
creates a stored property, which is automatically backed up by a variable (not directly accessible though). Setting a value to that property is translated in setting the value in the property, and similarly for getting.
Instead:
var y = { get { return x + 5 } set { x = newValue - 5} }
will create a computed property, which is not backed up by a variable - instead you have to provide the implementation of the getter and/or setter, usually reading and writing values from another property and more generally as a result of a computation (hence the computed property name)
Suggested reading: Properties
Note: your code:
var variable2: Int { get{ return variable2 } set (newValue){ } }
is wrong because in the get
you are trying to return itself, which means calling get
recursively. And in fact the compiler will warn you with a message like Attempting to access 'variable2' within its own getter
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With