Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does setting the same value for a property still call willSet and didSet?

Tags:

swift

If I set a property value to the same value as it is currently set to, will willSet and didSet get called? This is important to know when you have side effects occurring in these functions.

like image 378
Richard Venable Avatar asked Aug 28 '14 16:08

Richard Venable


People also ask

Is didSet called on initialization?

willSet and didSet observers are not called when a property is first initialized. They are only called when the property's value is set outside of an initialization context.

What is difference between willSet and didSet in Swift?

willSet is called before the data is actually changed and it has a default constant newValue which shows the value that is going to be set. didSet is called right after the data is stored and it has a default constant oldValue which shows the previous value that is overwritten.

What is willSet and didSet?

willSet is called just before the value is stored. didSet is called immediately after the new value is stored.

What is the use of didSet in Swift?

Swift's solution is property observers, which let you execute code whenever a property has changed. To make them work, we use either didSet to execute code when a property has just been set, or willSet to execute code before a property has been set.


2 Answers

Yes, willSet and didSet get called even when setting to the same value. I tested it in a playground:

class Class1 {
    var willSetCount = 0
    var didSetCount = 0
    var var1: String = "A" {
        willSet {
            willSetCount++
        }
        didSet {
            didSetCount++
        }
    }
}

let aClass1 = Class1()  // {0 0 "A"}
aClass1.var1 = "A"      // {1 1 "A"}
aClass1.var1 = "A"      // {2 2 "A"}

If you want to prevent side effects from happening when the same value is being set, you can compare the value to newValue/oldValue:

class Class2 {
    var willSetCount = 0
    var didSetCount = 0
    var var1: String = "A" {
        willSet {
            if newValue != var1 {
                willSetCount++
            }
        }
        didSet {
            if oldValue != var1 {
                didSetCount++
            }
        }
    }
}

let aClass2 = Class2()  // {0 0 "A"}
aClass2.var1 = "A"      // {0 0 "A"}
aClass2.var1 = "B"      // {1 1 "B"}
like image 66
Richard Venable Avatar answered Sep 22 '22 07:09

Richard Venable


Yes, it does. You could have a property of type that does not conform to Equatable protocol and then "same value" would not make sense. willSet and didSet isn't called only when the value is set inside initializer.

like image 30
Marián Černý Avatar answered Sep 24 '22 07:09

Marián Černý