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被调用。
我希望只有foo的num被呼叫。
如果我删除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来解决这个问题。
protocol FooType: AnyObject {
var num:Int { get set }
}