簡介
構(gòu)造過程:結(jié)構(gòu)體在和類在創(chuàng)建實例的過程中需要進行一些初始化工作渊迁,這個過程等稱之為構(gòu)造過程
析構(gòu)過程:類和結(jié)構(gòu)體在最后被釋放的時候需要進行一些釋放資源的操作楼眷,這個過程稱之為析構(gòu)過程
構(gòu)造函數(shù)
類和結(jié)構(gòu)體的實例在構(gòu)造過程中會調(diào)用一種特殊的init方法贴谎,稱之為構(gòu)造函數(shù)慧库。構(gòu)造函數(shù)沒有返回值逛揩,可以重載柠傍。多個構(gòu)造函數(shù)重載的情況下,運行環(huán)境會根據(jù)它的參數(shù)標簽或者是參數(shù)列表調(diào)用合適的構(gòu)造函數(shù)辩稽。
- 默認構(gòu)造函數(shù)
如果我們沒有編寫任何的構(gòu)造函數(shù)惧笛,類和結(jié)構(gòu)體會提供一個默認的構(gòu)造函數(shù)。下面的例子中逞泄,rect的初始化就調(diào)用了默認的構(gòu)造函數(shù)
class Rectangle {
var width: Double = 0.0
var height: Double = 0.0
}
var rect = Rectangle()
rect.height = 1.0
rect.width = 2.0
類和結(jié)構(gòu)體的默認構(gòu)造函數(shù)有所不同患整,結(jié)構(gòu)體的默認構(gòu)造函數(shù)可以按照從上到下的順序把屬性名作為參數(shù)標簽,依次提供參數(shù)喷众,代碼示例如下:
struct Rectangle {
var width: Double
var height: Double
//默認構(gòu)造函數(shù)實現(xiàn)
init(width: Double, height: Double) {
self.width = width;
self.height = height;
}
}
var rect = Rectangle.init(width: <#T##Double#>, height: <#T##Double#>)
-
構(gòu)造函數(shù)與存儲屬性初始化
構(gòu)造函數(shù)的主要作用就是初始化實例各谚,其中包括存儲屬性和其他屬性的初始化。(在不聲明為可選類型的情況下到千,如果存儲屬性在構(gòu)造函數(shù)中沒有初始化昌渤,在定義的時候也沒有初始化,那么就會發(fā)生編譯錯誤)如下:
所以我們在創(chuàng)建一個類或者是結(jié)構(gòu)體的時候憔四,存儲屬性如果沒有初初始化膀息,需要初始化存儲屬性:
class Rectangle {
let num: Int
var width: Double = 0.0
var height: Double
var name: String?
init() {
self.num = 5
self.height = 0.0
self.name = "haha"
}
}
注意:常量類型只能在定義的時候賦值,而在構(gòu)造函數(shù)中了赵,常量類型可以不遵守這個規(guī)則潜支。在別的方法中不行。另外柿汛,如果我們在定義的時候不能確定存儲屬性的值冗酿,可以將其聲明為可選類型。
- 使用參數(shù)標簽
為了增強程序的可讀性苛茂,swift在方法和函數(shù)中可以使用參數(shù)標簽已烤。例如:
class Rectangle {
var width: Double
var height: Double
init(W width: Double, H height: Double) {
self.width = width
self.height = height
}
}
var rect = Rectangle.init(W: <#T##Double#>, H: <#T##Double#>)
//如果沒有聲明參數(shù)標簽鸠窗,參數(shù)名會直接作為參數(shù)標簽使用
var rect = Rectangle.init(width: <#T##Double#>, height: <#T##Double#>)
一般情況下訪問屬性時self可以省略妓羊,但是局部變量和常量命名與屬性名發(fā)生沖突的時候,屬性前面一定要加上self
- 構(gòu)造函數(shù)重載
swift中的構(gòu)造函數(shù)可以有多個稍计,但是它們的參數(shù)列表不同躁绸,這些構(gòu)造函數(shù)構(gòu)成重載
class Rectangle {
var width: Double
var height: Double
init(width: Double, height: Double) {
self.width = width
self.height = height
}
init(W width: Double, H height: Double) {
self.width = width
self.height = height
}
}
上面代碼中,兩個構(gòu)造函數(shù)就是重載關系,雖然他們的功能是一樣的净刮,但是他們的參數(shù)列表不同(參數(shù)標簽不同)
構(gòu)造函數(shù)代理
為了減少多個構(gòu)造函數(shù)之間的代碼重復剥哑,在定義構(gòu)造函數(shù)時可以通過調(diào)用其他構(gòu)造函數(shù)來完成實例的部分構(gòu)造過程,這個過程稱之為構(gòu)造函數(shù)代理淹父。構(gòu)造函數(shù)代理在結(jié)構(gòu)體和類中的使用方式不同株婴。
結(jié)構(gòu)體構(gòu)造函數(shù)代理
struct Rectangle {
var width: Double
var height: Double
init(width: Double, height: Double) {
self.width = width
self.height = height
}
init(W width: Double, H height: Double) {
self.init(width: width, height: height)
}
init() {
self.init(width: 1.0, height: 2.0)
}
}
類構(gòu)造函數(shù)代理
由于類有繼承關系,所以類構(gòu)造函數(shù)代理分為橫向代理和向上代理
橫向代理類似于結(jié)構(gòu)體類型構(gòu)造函數(shù)代理暑认,發(fā)生在同一類內(nèi)部困介,這種構(gòu)造函數(shù)稱之為便利構(gòu)造函數(shù)
向上代理發(fā)生在繼承情況下,在子類構(gòu)造過程中要先調(diào)用父類構(gòu)造函數(shù)蘸际,初始化父類的存儲屬性座哩,這種構(gòu)造函數(shù)稱為指定構(gòu)造函數(shù)
橫向代理如下
class Rectangle {
var width: Double
var height: Double
init(width: Double, height: Double) {
self.width = width
self.height = height
}
convenience init(W width: Double, H height: Double) {
self.init(width: width, height: height)
}
convenience init() {
self.init(width: 1.0, height: 2.0)
}
}
convenience表示遍歷構(gòu)造函數(shù),這說明我們定義的構(gòu)造函數(shù)時橫向代理調(diào)用其他構(gòu)造函數(shù)
向上代理
析構(gòu)函數(shù)
與構(gòu)造過程相反粮彤,實例在最后釋放的時候需要清除一些資源根穷,這個過程就是析構(gòu)過程,析構(gòu)過程也會調(diào)用一個特殊的方法 deinit 导坟,成為析構(gòu)函數(shù)屿良。析構(gòu)函數(shù)沒有返回值,也沒有參數(shù)惫周,也不需要參數(shù)的小括號管引,所以不能重載。(析構(gòu)函數(shù)只適用于類闯两,不適用于枚舉和結(jié)構(gòu)體)
class Test {
var width: Double
var height: Double
init(width: Double, height: Double) {
self.width = width
self.height = height
}
convenience init(W width: Double, H height: Double) {
self.init(width: width, height: height)
}
convenience init() {
self.init(width: 1.0, height: 2.0)
}
deinit {
print("調(diào)用析構(gòu)函數(shù)")
}
}