Initialization
Classes 與 structures 在建立 instance 時,所有的 property 一定都需要有初始值,
若在宣告 property 時未給予預設值,就必須在 initializer 內來設定。
Initializer 宣告
基本宣告
class MyClass {
var property: Int
var property2 = 123
init () {
property = 123
}
}
客製化宣告
class MyClass {
var property: Int
init (para: Int) {
property = para
}
}
預設 initializer
若 property 全都有預設值,就會自動產生一個不需帶任何參數的 initializer。
但如果有宣告其他的 initializer,這個 initializer 就不會自動產生。
Structures 的 initializer
之前有介紹到,如果 structures 有 property,會自動產生帶有參數的 initializer。
struct MyStruct {
var property: Int
}
let s = MyStruct(property: 123)
Designated initializers & convenience initializers
Designated initializers 是 class 內最主要的初始化方法,
class 內至少要有一個 designated initializer。
Convenience initializers 是 class 內次要的初始化方法,
class 內可以沒有 convenience initializers。
宣告方法
Designated initializers
class MyClass {
init() {
}
}
Convenience initializers
class MyClass {
convenience init () {
}
}
重點規則
每個 subclass 內的 designated initializers 一定要呼叫 superclass 的 designated initializers。
class MyClass {
init() {
}
init(para: String) {
}
}
class MyClass2: MyClass {
init(para: Int) {
super.init(para: “123")
}
}
每個 convenience initializers 一定要呼叫同一個 class 內其他的 initializers。
class MyClass {
init() {
}
convenience init(para: Int) {
self.init()
}
}
Convenience initializers 最後一定要呼叫到 designated initializers。
class MyClass {
}
class MyClass2: MyClass {
init(para: String) {
}
convenience init(para: Int) {
self.init(para: “123")
}
convenience init(para: Int, para2: Int) {
self.init(para: para)
}
}
繼承 initializers
Swift 的 subclass 並不會繼承 superclass 的 initializers。
但如果 subclass 沒有宣告任何 designated initializers,
subclass 會自動繼承 superclass 所有的 initializers。
class MyClass {
init(para: Int) {
}
}
class MyClass2: MyClass {
}
let c = MyClass2(para:123)
如果 subclass 重新宣告 superclass 全部的 designated initializers,
那麼 subclass 就會自動繼承 superclass 所有的 convenience initializers。
class MyClass {
init() {
}
init(para: Int) {
}
convenience init(para: String) {
}
}
class MyClass2: MyClass {
override init(para: Int) {
super.init()
}
}
let c = MyClass2(para:”123")
Fallible initializers
可以讓初始化後回傳 Optionals 的 nil,代表初始化失敗。
class MyClass {
init?(para: String) {
if para.isEmpty { return nil }
}
}
也可以讓 subclass override superclass 的 fallible initializers,
變成 non fallible initializers。
class MyClass {
init() {
}
init?(para: String) {
if para.isEmpty {return nil}
}
}
class MyClass2: MyClass {
override init(para: String) {
super.init()
}
}
必要 initializer
如果 subclass 有定義自己的 designated initializers,
那 subclass 就必須一定要實作 superclass 上有加 required 的 initializer。
class MyClass {
required init(para: String) {
}
}
class MyClass2: MyClass {
init() {
}
required init(para: String) {
}
}
透過 closure 設定 property 初始值
可以直接透過 closure 來設定 property,在 instance 建立時,會同時呼叫這個 closure 來設值,
要記住切勿在此 closure 內使用其他的 property,因為這時候的 instance 尚未被建立,
其他的 property 可能還沒被初始化。
class MyClass {
let para = { ()->String in
return “123”
}()
}
Deinitialization
Deinitializer 會在 instance 被 dealloc 時被自動呼叫,也沒有任何方法能夠主動去呼叫。
class MyClass {
deinit {
print("deinit")
}
}
let c = MyClass()
c = nil