標籤:swift ios 構造器 析構器
構造過程
Swift的構造過程通過定義構造器來實現。不過與Objective-C不同的是,Swift的構造器不需要返回值,同樣也不需要表明Func。
另外值得提的是,當構造器中為儲存型屬性賦值時,不會觸發屬性觀測器。
定製化的構造過程
1. 除了預設的構造器外,我們可以通過增加參數的方式來為其添加自訂的建構函式或者叫便捷構造器(covenience initializer)。2. 構造器自動產生外部參數名,如果不希望則用"_"底線來屏蔽掉。3. 若屬性為Optional類型的,在構造器中如果未賦值,編譯器預設賦值為nil。4. 只要在構造結束前常量的屬性確定,則可在構造過程的任意時間點修改常量屬性,但不能在子類中修改。5. 若不寫init也會有預設構造器。6. 結構體有預設的逐一成員構造器。
類的繼承和構造過程
構造器代理
我們可以通過調用其他的構造器來完成部分構造過程,且只能在構造器內部調用self.init
強調一點的是,類的所有儲存型屬性,包括繼承自父類的,必須在構造過程中設定初始值。
構造器鏈
在蘋果的語言文檔中,給構造器代理調用說明了三條原則:
1. 指定構造器必須調用其直接父類的指定構造器。2. 便利構造器必須調用同一類中定義的其他構造器。3. 便利構造器最終以調用一個指定構造器結束。
簡單來講為指定構造器向上調用,而便利構造器橫向調用。
二段式的構造過程
第一階段: 每個儲存型屬性通過引入它們的類構造器來設初始化值。第二階段: 在準備使用前進一步定製。
為了保證二段式構造順利完成,編譯器會執行4種有效安全檢查:
1. 指定構造器必須保證其所在類引入的所有屬性都初始化完成之後才能將其他任務向上代理給父類構造器。2. 指定構造器須先調用父類的構造器才能為繼承來的屬性賦新值。3. 便利構造器須先調用其他構造器,再能賦新值。不然則可能會被覆蓋掉。4. 構造器在第一階段完成前,不能調用任何執行個體方法,訪問執行個體屬性及self。
構造器的繼承和重載
Swift的子類不會預設繼承父類的構造器,這種機制可以防止一個父類的簡單構造器被一個更專業的子類繼承,並被錯誤的用來建立子類的執行個體。我們可以在自己定製的子類中,重載父類的構造器。與方法,屬性和下標指令碼不同,重載init方法時沒必要使用override關鍵字。
但滿足特殊條件時則可以自動繼承父類的構造器,有兩個原則:
1. 若子類沒有定義指定構造器,則繼承父類的指定構造器。2. 若子類提供所有父類指定構造器實現,將自動繼承便利構造器。
指定構造器和便利構造器的文法
初始化過程遵守上面原則即可。不過類不同於結構體,沒有逐一初始化器。
通過閉包或者函數設定屬性值
一般使用代碼塊後面會加空的小括弧,表明立即執行此閉包,將返回值賦給屬性而不是閉包本身賦值給屬性。閉包初始化屬性時,其它部分還未初始化,這意味不允許在閉包中訪問其它屬性,self,也不允許使用點文法。
例子:棋盤
這裡結構體持有的棋盤顏色數組使用了閉包來建立。不過我們注意到數組的寫法是[Bool]而不是之前的Bool[] 這是當前(14.7.11)蘋果在Xcode-beta3中對Swift文法最新的修改。
析構過程
析構屬於C++中常提到的概念,類似於oc中的dealloc,java中finalize。當一個執行個體即將離開堆記憶體時,我們會調用deinit函數,來進行一些額外的清理工作。
自動引用計數
引用迴圈問題
在OC中,常常在block中調用self前會使用__weak來修飾weakSelf,來防止由於block的變數捕獲而造成的引用迴圈問題。同樣在Swift中也會有這種情況,不過Swift除了使用弱引用外,添加了一種無主引用。需要注意的是,弱引用必須為變數而不是常量。
那麼無主引用(unowned)是什麼呢。無主引用使用unowned關鍵字,修飾永遠有值的內容,注意的是,執行個體如果被銷毀後訪問無主引用會引發crash。
無主引用的使用情境,有時候我們有兩個屬性互相指向對方,而且都不能為nil, 這時候需要一個屬性標記為無主,另一個為隱式解析可選屬性(使用!)。
例:
我們可以注意到Country中有個屬性為City, 而capitalCity在初始化時將country指向了自己,所以這時候我們將City的country設計為無主引用而Country的capital則為隱式可選屬性(!)。
閉包引起的強循環參考
閉包在捕獲值時,尤其是self時,需要特別小心,這時我們要在定義參數列表時將其捕獲的執行個體修飾為unowned
注意參數列表中使用weak還是unowned關鍵字與被修飾的內容能否為nil有關。如果執行個體可能為nil則堅決不要使用unowned來修飾。
這篇部落客要描述了Swift中執行個體的構造以及析構過程。以上為本篇部落格全部內容,歡迎勘誤討論。
這篇文章以及其他所有文章關於Swift的playground都收集在https://github.com/Rannie/PlaygroundSwift