为什么调用此属性的 didSet

  • 本文关键字:属性 didSet 调用 swift
  • 更新时间 :
  • 英文 :

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 }
}

最新更新