为什么 属性 观察器不适用于 类?
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
以便可以替换变量值。
使用游乐场。
我有以下结构:
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
以便可以替换变量值。