jhamPac jhamPac - 4 months ago 9
Swift Question

What are the fundamental differences between set and didSet?

I understand that one is a setter and the other is a property observer. My question is how do they differ in behavior and when would you use one over the other. Don't they do pretty much the same thing? For example:

var foo: String {
set {
run code when set
}
}

var foo: String {
didSet {
run code when set
}
}

Answer

They do not do pretty much the same thing, on the contrary they have totally different purposes. The get and the setare used on computed properties. For instance, take this example structure that has no real use, but is a good demo.

struct test {
    var x = 5
    var y = 5
    var number: Int {
        get {
            return x * y
        }
        set (newValue){
            x = newValue / 2
            y = newValue / 2
        }
    }
}

var s = test()
s.number //25
s.number = 100
s.x //50
s.number //2500

So, as you can see, the variable number isn't a variable in the traditional sense, it is a computed property. So, when I call s.number I get the product of x and y. Also, you would use the set to change other variables (not the computed property itself) in the structure. So, I set x and y to different values based on the newValue. This idea of a computed property can be used in place of a function and I find is very useful in simplifying retrieval of data from a function. For instance, you could have a structure that has a distance in kilometers and you might want that in miles very frequently. So, you could create a computed property miles for miles that computes the number of kilometers with the get method, and changes the number of kilometers with the setter if a you set miles to in your program.


Now, for the didSet and willSet. You can use these to notify your structure of a value change. For instance, an averageTracker.

struct averageTracker {
    var total: Double = 0 {
        didSet {
            numEntries++
        }
    }
    var numEntries: Double = 0
    var average: Double {
        get {
            return total / numEntries
        }
    }
}


var ave = averageTracker()
ave.total += 10
ave.total += 20
ave.average //15

Notice how the didSet is actually on a variable that contains a value, that is, it is not a computed property. Also, I used a computed property average to get the average. Overall, I hope I cleared up your confusion regarding this very powerful aspect of Swift.