为什么 属性 观察器不适用于 类?

Why property observer doesn't work with classes?

使用游乐场。

我有以下结构:

struct Foo {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

我从它声明了一个实例作为 属性 观察者,name 的默认值为“James”,age 的默认值为 33:

var myFoo = Foo(name: "James", age: 33) {
    willSet {
        print("my foo will be: \(newValue)")
    }
    didSet {
        print("my foo was: \(oldValue)")
    }
}

尝试编辑实例的 name 时:

myFoo.name = "John"

我可以在日志中看到:

my foo will be: Foo(name: "John", age: 33)

my foo was: Foo(name: "James", age: 33)

这是我的期望。但是,当将 Foo 声明为 class 而不是结构时:class Foo 和 运行 完全相同的代码,日志中不会出现任何内容。

背后的原因是什么?

因为class是引用类型,而结构是值类型。

  • 假设 Foo 是一个 class。 myFoo 仅供参考。说 myFoo.name = "John" 就地改变对象;没有新值分配给 myFoo,因此 setter 观察者没有什么可观察的。

  • 假设 Foo 是一个结构体。那是一个值类型。它不能就地改变。因此,说 myFoo.name = "John" 实际上用新结构替换了变量 myFoo 中的结构;设置变量和 setter 观察者触发。


这也是为什么你可以对 class 说 myFoo.name = "John" 即使 myFoo 是用 let 声明的(即对象只是在适当的地方发生了变化),但是你不能用结构来做到这一点——你必须用 var 声明 myFoo 以便可以替换变量值。