Phase 1
1. A designated or convenience initializer is called on a class.
2. Memory for a new instance of that class is allocated. The
memory is not yet initialized.
3. A designated initializer for that class confirms that all stored
properties introduced by that class have a value. The memory for
these stored properties is now initialized.
4. The designated initializer hands off to a superclass initializer to
perform the same task for its own stored properties.
5. This continues up the class inheritance chain until the top of
the chain is reached.
6. Once the top of the chain is reached, and the final class in the
chain has ensured that all of its stored properties have a value,
the instance’s memory is considered to be fully initialized, and
phase 1 is complete.
Phase 2
1. Working back down from the top of the chain, each designated
initializer in the chain has the option to customize the instance further. Initializers are now able to access self and can modify its
properties, call its instance methods, and so on.
2. Finally, any convenience initializers in the chain have the option
to customize the instance and to work with self.
上面總結(jié):
第一階段指, 初始化從上到下初始化完成, 從上到下指父類
第二階段指, 初始化鏈結(jié)束后, 可以對繼承的屬性進(jìn)行修改, 對方法進(jìn)行調(diào)用
Tips
- 初始化方法中給屬性賦值, 不會走
willSet
和didSet
, 但在初始化方法中調(diào)用的其他方法, 其他方法給屬性賦值會走上面的兩個方法
class A {
init() {
}
convenience init(k: Int) {
self.init()
}
}
class AA: A {
var a = 10 {
didSet {
print("\(a)")
}
}
override init() {
self.a = 10
super.init()
self.a = 20
self.run()
self.a = 40
}
convenience init(a: Int) {
self.init()
self.a = 50
}
func run() {
self.a = 30
}
}
let a = AA(a: 1)
//print
30
- 便利構(gòu)造器, 在使用
self
之前, 必須調(diào)用自己的指定構(gòu)造器. - 指定構(gòu)造器, 在訪問方法或者父類的屬性之前, 必須調(diào)用父類的指定構(gòu)造器
- 調(diào)用父類構(gòu)造器之前, 必須給自己的沒賦值的確定屬性(指不是可選, 沒有使用
?!
) 賦值. - 如果子類的屬性都有默認(rèn)值, 或者是可選的, 即使子類會自動繼承父類的構(gòu)造器, 但如果子類有其他的指定構(gòu)造器, 這個就失效了.
class C {
var a: Int
init(a: Int) {
self.a = a
}
}
class CC: C {
var b = 10
}
let c = CC(a: 10)
print(c.a)
// print
10
- 失敗的初始化
class D {
init?() {
return nil
}
}
let d = D()
print(d)
// print
nil