欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Swift中初始化init的方法小結(jié)

 更新時(shí)間:2018年04月27日 08:33:46   作者:yanging  
Swift有著超級(jí)嚴(yán)格的初始化方法,不僅強(qiáng)化了designated初始化方法的地位,所有不加修飾的init方法都需要在方法中確保非Optional的實(shí)例變量被賦值初始化,下面這篇文章主要給大家介紹了關(guān)于Swift中初始化init的相關(guān)資料,需要的朋友可以參考下。

前言

我們?cè)谏钊氤跏蓟椒ㄖ?,不妨先再想想Swift中的初始化想要達(dá)到一種怎樣的目的。

其實(shí)就是安全。在Objective-C中,init方法是非常不安全的:沒(méi)有人能保證init只被調(diào)用一次,也沒(méi)有人保證在初始化方法調(diào)用以后,實(shí)例的各個(gè)變量都完成初始化,甚至如果在初始化里使用屬性進(jìn)行設(shè)置的話,還可能會(huì)造成各種問(wèn)題。雖然Apple也明確說(shuō)明了不應(yīng)該在init中使用屬性來(lái)訪問(wèn),但這并不是編譯器強(qiáng)制的,因此還是會(huì)有很多開發(fā)者犯這樣的錯(cuò)誤。

所以Swift有了超級(jí)嚴(yán)格的初始化方法。一方面,Swift強(qiáng)化了designated初始化方法的地位。Swift中不加修飾的init方法都需要在方法中保證所有非Optional的實(shí)例變量被賦值初始化,而在子類中也強(qiáng)制 (顯式或隱式地)調(diào)用super版本的designated初始化,所以無(wú)論如何走何種路徑,被初始化的對(duì)象總是可以完成完整的初始化的。

Swift 的初始化和 Objective-C 有一個(gè)很大的不同,Objective-C 默認(rèn)會(huì)給每個(gè)屬性賦一個(gè)空值,如 nil 或者 0,但 Swift 的初始化更加嚴(yán)格,需要開發(fā)者自己顯示指定類成員的初始值,否則編譯會(huì)報(bào)錯(cuò)。

結(jié)構(gòu)體初始化

如果結(jié)構(gòu)體沒(méi)有實(shí)現(xiàn)任何初始化函數(shù),Swift 默認(rèn)給生成一個(gè)包含所有成員變量的初始化構(gòu)造器。

struct RocketConfiguration {
 let name: String = "Athena 9 Heavy"
 let numberOfFirstStageCores: Int
 let numberOfSecondStageCores: Int
 let numberOfStageReuseLandingLegs: Int
}

如果使用如下的代碼初始化這個(gè)結(jié)構(gòu)體:

let athena9Heavy = RocketConfiguration()

將產(chǎn)生編譯錯(cuò)誤,如下圖:


有兩種做法可以消除錯(cuò)誤,聲明結(jié)構(gòu)體成員時(shí)即賦值,如下:

struct RocketConfiguration {
 let name: String = "Athena 9 Heavy"
 let numberOfFirstStageCores: Int = 3
 let numberOfSecondStageCores: Int = 1
 let numberOfStageReuseLandingLegs: Int? = nil
}

let athena9Heavy = RocketConfiguration()

但這種情況下,成員變量無(wú)法再修改,除非將let改成var?;蛘呤褂媚J(rèn)的初始化構(gòu)造器,給每個(gè)成員賦一個(gè)初始化的值:

struct RocketConfiguration {
 let name: String = "Athena 9 Heavy"
 let numberOfFirstStageCores: Int
 let numberOfSecondStageCores: Int
 let numberOfStageReuseLandingLegs: Int
}

let athena9Heavy = RocketConfiguration(numberOfFirstStageCores: 3, numberOfSecondStageCores: 1, nominalBurnTime: nil)

類的初始化

和結(jié)構(gòu)體不同的是,類必須自己聲明初始化構(gòu)造器:

class LaunchSite {
 let name: String
 let coordinates: (String, String)
 
 init(name: String, coordinates: (String, String)) {
  self.name = name
  self.coordinates = coordinates
 }
}

如果去掉上面的init函數(shù),將產(chǎn)生編譯錯(cuò)誤,如下圖:


指定構(gòu)造器(Designated Initializers)

指定構(gòu)造器對(duì)所有沒(méi)有默認(rèn)值的非可選屬性進(jìn)行初始化。

class RocketComponent {
 let model: String
 let serialNumber: String
 let reusable: Bool
 
 // Init #1a - Designated
 init(model: String, serialNumber: String, reusable: Bool) {
  self.model = model
  self.serialNumber = serialNumber
  self.reusable = reusable
 }
} 

初始化調(diào)用:

let payload = RocketComponent(model: "RT-1", serialNumber: "234", reusable: false)

便利構(gòu)造器(Convenience Initializers)

便利構(gòu)造器是在init前加一個(gè)關(guān)鍵子convenience,它為一些屬性提供默認(rèn)值:

// Init #1b - Convenience
convenience init(model: String, serialNumber: String) {
 self.init(model: model, serialNumber: serialNumber, reusable: false)
}

這樣,在初始化時(shí)就無(wú)需給所有屬性賦值,如下:

let fairing = RocketComponent(model: "Serpent", serialNumber: "0")

便利構(gòu)造器通常要調(diào)用類自身的便利構(gòu)造器或者指定構(gòu)造器,不管是哪種,最終都要調(diào)用指定構(gòu)造器。如下圖:


子類的初始化

class Tank: RocketComponent {
 let encasingMaterial: String
}

這段代碼會(huì)產(chǎn)生編譯錯(cuò)誤:


encasingMaterial 沒(méi)有初始化值,Swift 的原則是,所有屬性在初始化階段都要完成賦值,因?yàn)?Swift 不會(huì)給屬性賦默認(rèn)值,需要開發(fā)者自己完成。簡(jiǎn)單做法是給encasingMaterial屬性一個(gè)默認(rèn)值:

class Tank: RocketComponent {
 let encasingMaterial: String = "Aluminum"
}
let fuelTank = Tank(model: "Athena", serialNumber:"003", reusable: true)

或者聲明一個(gè)指定構(gòu)造器:

class Tank: RocketComponent {
 let encasingMaterial: String
 init(model: String, serialNumber: String, reusable: Bool, encasingMaterial: String) {
  self.encasingMaterial = encasingMaterial
  super.init(model: model, serialNumber: serialNumber, reusable: reusable)
 }
}
let fuelTank = Tank(model: "Athena", serialNumber:"003", reusable: true, encasingMaterial: "Aluminum")

需要注意的是,子類自身屬性的初始化需要在調(diào)用父類的初始化構(gòu)造器前完成,如下代碼

init(model: String, serialNumber: String, reusable: Bool, encasingMaterial: String) {
  super.init(model: model, serialNumber: serialNumber, reusable: reusable)
  self.encasingMaterial = encasingMaterial
 }

將產(chǎn)生編譯錯(cuò)誤,如下圖:


父類屬性的初始化,需要在調(diào)用父類構(gòu)造器之后:如下:

init(model: String, serialNumber: String, reusable: Bool, encasingMaterial: String) {
 self.encasingMaterial = encasingMaterial
 super.init(model: model, serialNumber: serialNumber, reusable: reusable)
 self.model = model + "-X"
}

要先調(diào)用父類的構(gòu)造器,以防止先給屬性賦值了然后才調(diào)用父類而把以前的賦值覆蓋了。若把self.model放在super.init之前,會(huì)產(chǎn)生編譯錯(cuò)誤:


初始化調(diào)用順序

  • 便利構(gòu)造器需要調(diào)用類自身的便利構(gòu)造器或指定構(gòu)造器,最終要調(diào)用類自身的指定構(gòu)造器。
  • 子類的指定構(gòu)造器需要調(diào)用父類的指定構(gòu)造器

如下圖:


這篇文章總結(jié)自以下兩篇文章

想了解更詳細(xì)的 Swift 初始化過(guò)程可作參考,建議大家創(chuàng)建一個(gè) playground,跑一遍文章中的例子,能加深理解。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Swift設(shè)置UILabel內(nèi)邊距的實(shí)例代碼

    Swift設(shè)置UILabel內(nèi)邊距的實(shí)例代碼

    有時(shí)候,我們需要一個(gè)顯示文字,又想這些文字與邊界之間有自定義的邊距,所以下面這篇文章主要給大家介紹了關(guān)于Swift設(shè)置UILabel內(nèi)邊距的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • Swift讀取App的版本信息與PCH文件詳解

    Swift讀取App的版本信息與PCH文件詳解

    這篇文章主要介紹了Swift讀取App的版本信息與PCH文件的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-03-03
  • Swift HTTP加載請(qǐng)求Loading Requests教程

    Swift HTTP加載請(qǐng)求Loading Requests教程

    這篇文章主要為大家介紹了Swift HTTP加載請(qǐng)求Loading Requests教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Swift自動(dòng)調(diào)整視圖布局AutoLayout和AutoresizingMask功能詳解

    Swift自動(dòng)調(diào)整視圖布局AutoLayout和AutoresizingMask功能詳解

    這篇文章主要為大家介紹了Swift自動(dòng)調(diào)整視圖布局AutoLayout和AutoresizingMask功能及使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Swift中swift中的switch 語(yǔ)句

    Swift中swift中的switch 語(yǔ)句

    本文給大家介紹了swift中的swift語(yǔ)句,以及和c語(yǔ)音中的寫法區(qū)別,本文介紹的非常詳細(xì),需要的朋友參考下
    2016-12-12
  • Swift中排序算法的簡(jiǎn)單取舍詳解

    Swift中排序算法的簡(jiǎn)單取舍詳解

    對(duì)于排序算法, 通常簡(jiǎn)單的, 為大家所熟知的有, 選擇排序, 冒泡排序, 快速排序, 當(dāng)然還有哈希, 桶排序之類的, 本文僅比較最為常見(jiàn)的選擇, 冒泡和快排,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2018-03-03
  • Swift重構(gòu)自定義空等運(yùn)算符 “??=” 實(shí)例

    Swift重構(gòu)自定義空等運(yùn)算符 “??=” 實(shí)例

    這篇文章主要為大家介紹了Swift重構(gòu)自定義空等運(yùn)算符 “??=” 實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • swift實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器

    swift實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器

    這篇文章主要為大家詳細(xì)介紹了swift實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 用SwiftUI實(shí)現(xiàn)3D Scroll滾動(dòng)效果的實(shí)現(xiàn)代碼

    用SwiftUI實(shí)現(xiàn)3D Scroll滾動(dòng)效果的實(shí)現(xiàn)代碼

    這篇文章主要介紹了用SwiftUI實(shí)現(xiàn)3D Scroll效果的實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)
    2020-04-04
  • 探討Swift數(shù)組和字典

    探討Swift數(shù)組和字典

    Swift數(shù)組是具體的。他不同于Objective-C的的NSArray和NSMutableArray里的類,它可以存儲(chǔ)任何類型的對(duì)象,不提供有關(guān)它們返回的對(duì)象的性質(zhì)的任何信息
    2015-12-12

最新評(píng)論