0%

Swift 中的 willSet 和 didSet

willSet 和 didSet 在 Swift 中用于监控存储型属性的变化,被称为属性观察器(Property Observers)。其用法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Person {

var name: String = "Guest" {

willSet {
print("Name: willSet")
}

didSet {
print("Name: didSet")
}
}

init(name: String) {
self.name = name
}
}

let roger = Person(name: "Roger")
roger.name = "Rafa" // 此时触发属性观察器

需要注意的是:

  • 属性观察器只可用于存储型属性,不能用在计算型属性;
  • 属性观察器不会监控属性初始化过程,即属性首次赋值的时候是不会被监控的,如上面代码的构造函数是不会被监控的,即使属性声明的时候已经初始化;
  • 但是不代表构造函数执行一定不会触发属性观察器,下面会举例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Person {

var name: String = "Guest" {

willSet {
print("Name: willSet")
}

didSet {
print("Name: didSet")
}
}
}

class Student: Person {

var studentNumber: Int

init(studentNumber: Int, name: String) {
self.studentNumber = studentNumber
super.init()

self.name = name
}
}

let andy = Student(studentNumber: 123456, name: "Andy") // 构造函数触发属性观察器

在这个例子中,Student 类的构造函数完成了三件事:

  1. 初始化自身属性;
  2. 调用父类构造函数,初始化父类属性并完成构造过程,此时构造过程已经完成;
  3. 为父类的属性按照子类的要求设置默认值,此时虽然是在构造函数中完成,但实质上已经在做构造过程之后的事情了,这时属性的修改就会触发属性观察器。
  1. Setting the value of properties that the subclass declares.
  2. Calling the superclass’s initializer.
  3. Changing the value of properties defined by the superclass. Any additional setup work that uses methods, getters, or setters can also be done at this point.”

Excerpt From: Apple Inc. “The Swift Programming Language (Swift 4.1).” iBooks.