Consider this code:
class S {
var i: Int
init(i: Int) {
self.i = i
}
}
class C {
var prop1 = S(i: 0) {
didSet {
print("did set prop1, with i: \(prop1.i)")
}
}
}
var c = C()
print("i: \(c.prop1.i)")
var p = c.prop1
p.i = 1
print("i: \(c.prop1.i)")
c.prop1.i = 2
It prints:
i: 0
i: 1
i: 2
It prints 0, 1, 2
which is fairly obvious because S
is a class — a reference type — so when p
is actually a reference to the same instance of S
, we are just operating on that same instance.
However, here's something that was surprising to me. What happens if we change S to be a struct? i.e.
Replace:
class {
with:
struct {
The output becomes:
i: 0
i: 0
did set prop1, with i: 2
i: 2
S
is now a value type, so naturally, i
remains at 0 because p
is actually a copy of the struct held by the instance of C
. Here's what surprised me though. c.prop1.i = 2
copies the struct, sets the new value of i
(to 2
) and assigns it back to the instance of C
, triggering the didSet
observer.
I recently wrote some code where this behavior bit me because I wasn't counting on didSet
being triggered.
Beware!
Your feedback is valuable: Do you want more nuggets like this? Yes or No
.
.