protocol FooType {
var num:Int { get set }
}
class Foo: FooType {
var num: Int = 0 {
didSet {
print("Did set num")
}
}
}
class Bar {
var foo: FooType = Foo() {
didSet {
print("Did set Foo")
}
}
func changeNum(num:Int) {
foo.num = num
}
}
let bar = Bar()
bar.changeNum(5)
Did set num
Did set Foo
In this example, setting a property on foo causes Bar's didSet for foo to get called.
I would expect only Foo's num didSet to get called.
If I remove the protocol constraint of Bar's foo property to FooType, it behaves as I expected.
protocol FooType {
var num:Int { get set }
}
class Foo: FooType {
var num: Int = 0 {
didSet {
print("Did set num")
}
}
}
class Bar {
var foo = Foo() {
didSet {
print("Did set Foo")
}
}
func changeNum(num:Int) {
foo.num = num
}
}
let bar = Bar()
bar.changeNum(5)
Did set num
If I keep the conformance to FooType, but add a class constraint (FooType: class), it also behaves as expected.
protocol FooType: class {
var num:Int { get set }
}
class Foo: FooType {
var num: Int = 0 {
didSet {
print("Did set num")
}
}
}
class Bar {
var foo: FooType = Foo() {
didSet {
print("Did set Foo")
}
}
func changeNum(num:Int) {
foo.num = num
}
}
let bar = Bar()
bar.changeNum(5)
Did set num
If I remove the protocol completely and make Foo a struct rather than a class, we're back to both setters being called.
struct Foo {
var num: Int = 0 {
didSet {
print("Did set num")
}
}
}
class Bar {
var foo = Foo() {
didSet {
print("Did set Foo")
}
}
func changeNum(num:Int) {
foo.num = num
}
}
let bar = Bar()
bar.changeNum(5)
Did set num
Did set Foo
In the case changing Foo to a struct, I can see why it's happening... it mentions it in the swift documentation because a struct is a value type, it makes a copy, etc. (although I didn't expect it at first).
But the other cases I don't get...