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
在此示例中,在 foo 上设置属性会导致调用 Bar 的 didSet for foo。
我希望只有 Foo 的 num didSet 会被调用。
如果我删除 Bar 的 foo 属性对 FooType 的协议约束,它的行为符合我的预期。
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
如果我保持与 FooType 的一致性,但添加一个类约束(FooType:class(,它也会按预期运行。
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
如果我完全删除协议并使 Foo 成为结构而不是类,我们又回到了被调用的两个 setter。
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
在将 Foo 更改为结构的情况下,我可以看到为什么会发生这种情况......它在 swift 文档中提到了它,因为结构体是一种值类型,它会制作副本等(尽管我一开始没想到(。
但是其他情况我没有得到...
你可以通过一致性FooType到AnyObject 来解决这个问题
protocol FooType: AnyObject {
var num:Int { get set }
}