Initialization

  • swift中的initialization方法實(shí)現(xiàn)中不使用return不返回對(duì)象
    struct Fahrenheit {
        var temperature: Double
        init() {
            temperature = 32.0
        }
    }
    var f = Fahrenheit()
    print("The default temperature is \(f.temperature)° Fahrenheit")
    // Prints "The default temperature is 32.0° Fahrenheit"
    
  • 通過(guò)initializer創(chuàng)建初始值和在屬性定義時(shí)賦予默認(rèn)值筛圆,不會(huì)調(diào)用property observer
  • 由于init方法的方法名必須為init且不能重定義,所以括號(hào)內(nèi)的argument label特別重要综看。并且如果你沒有寫压恒,系統(tǒng)會(huì)為你提供挪钓。如果你不需要贡蓖,也可以使用_去掉(和其他函數(shù)方法參數(shù)結(jié)構(gòu)一樣)
  • 類中的屬性必須有default value嘁捷,在屬性定義和構(gòu)造器中賦值躏碳,如果不賦予初始化值要標(biāo)記成可選類型哀墓。不賦值的可選類型默認(rèn)為空趁餐,可以被理解成還沒有值,可以不在構(gòu)造器中賦值篮绰。
  • 常量屬性必須在定義時(shí)賦值后雷,或者在構(gòu)造器中賦值。對(duì)于類實(shí)例來(lái)說(shuō),只能在定義這個(gè)常量屬性的類中使用構(gòu)造器賦值臀突,不能再子類的構(gòu)造器中賦值勉抓。
    class SurveyQuestion {
        let text: String
        var response: String?
        init(text: String) {
            self.text = text
        }
        func ask() {
            print(text)
        }
    }
    let beetsQuestion = SurveyQuestion(text: "How about beets?")
    beetsQuestion.ask()
    // Prints "How about beets?"
    beetsQuestion.response = "I also like beets. (But not with cheese.)"
    
  • 當(dāng)屬性都有默認(rèn)值時(shí),且沒有自定義構(gòu)造器時(shí)候学,swift 會(huì)提供默認(rèn)構(gòu)造器藕筋。
    class ShoppingListItem {
        var name: String?
        var quantity = 1
        var purchased = false
    }
    var item = ShoppingListItem()
    
  • 對(duì)于結(jié)構(gòu)體而言,當(dāng)沒有自定義構(gòu)造器的時(shí)候梳码,會(huì)自動(dòng)生成逐一成員構(gòu)造器隐圾。不同于上面的默認(rèn)構(gòu)造器,逐一成員構(gòu)造器允許屬性在定義的時(shí)候沒有默認(rèn)值边翁。如果有自定義構(gòu)造器翎承,則不會(huì)生成默認(rèn)構(gòu)造器和逐一成員構(gòu)造器,這是為了防止錯(cuò)用符匾。如果想在自定義構(gòu)造器的同時(shí)也生成默認(rèn),使用擴(kuò)展(extension)
    struct Size {
        var width = 0.0, height = 0.0
    }
    let twoByTwo = Size(width: 2.0, height: 2.0)
    
  • 可以自定義多個(gè)構(gòu)造器瘩例,在復(fù)雜構(gòu)造器中使用self.init調(diào)用其他簡(jiǎn)單的自定義構(gòu)造器
    struct Rect {
        var origin = Point()
        var size = Size()
        init() {}
        init(origin: Point, size: Size) {
            self.origin = origin
            self.size = size
        }
        init(center: Point, size: Size) {
            let originX = center.x - (size.width / 2)
            let originY = center.y - (size.height / 2)
            self.init(origin: Point(x: originX, y: originY), size: size)
        }
    }
    
    let basicRect = Rect()
    // basicRect's origin is (0.0, 0.0) and its size is (0.0, 0.0)
    
    let originRect = Rect(origin: Point(x: 2.0, y: 2.0),
                        size: Size(width: 5.0, height: 5.0))
    // originRect's origin is (2.0, 2.0) and its size is (5.0, 5.0)
    
    let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
                        size: Size(width: 3.0, height: 3.0))
    // centerRect's origin is (2.5, 2.5) and its size is (3.0, 3.0)
    
  • 指定構(gòu)造器和普通構(gòu)造器格式一樣啊胶,至少要有一個(gè);便利構(gòu)造器在前面加上convenience關(guān)鍵字垛贤,可有可無(wú)焰坪。通常用必不可少的指定構(gòu)造器來(lái)創(chuàng)建實(shí)例,而使用便利構(gòu)造器來(lái)個(gè)性化定制子類聘惦。例如需要多個(gè)參數(shù)的指定構(gòu)造器某饰,可以創(chuàng)建需要一個(gè)參數(shù)的便利構(gòu)造器,在實(shí)現(xiàn)中調(diào)用指定構(gòu)造器善绎,其他參數(shù)傳默認(rèn)值黔漂,做到傳入更少參數(shù)便利創(chuàng)建實(shí)例,如下
     init(name: String) {
          self.name = name
      }
      convenience init() {
          self.init(name: "[Unnamed]]")
      }
    
  • 關(guān)于構(gòu)造器原則:1.指定構(gòu)造器必須調(diào)用其父類指定構(gòu)造器禀酱;2.便利構(gòu)造器必須調(diào)用類中其他構(gòu)造器炬守;3.便利構(gòu)造器必須最終調(diào)用指定構(gòu)造器。簡(jiǎn)單說(shuō):指定構(gòu)造器向上代理剂跟,便利構(gòu)造器橫向代理
  • swift中構(gòu)造器的兩個(gè)階段减途,第一個(gè)階段賦予所有變量默認(rèn)值,第二個(gè)階段變量在使用前靈活處理
  • 構(gòu)造器的安全檢查:1.必須指定所有存儲(chǔ)變量后才可以向上調(diào)用父類構(gòu)造器曹洽;2.指定構(gòu)造器必須在繼承屬性賦值前向上調(diào)用父類構(gòu)造器鳍置,否則賦值會(huì)被覆蓋;3.便利構(gòu)造器必須先調(diào)用其他構(gòu)造器送淆,后賦值税产,原理同上;4.第一階段結(jié)束前不允許調(diào)用和讀取任何實(shí)例屬性及實(shí)例方法
  • 第一階段:類調(diào)用指定或便利構(gòu)造器——為新實(shí)例分配內(nèi)存,沒有被完全初始化—— 指定構(gòu)造器為所有存儲(chǔ)屬性賦初始值砖第,所有存儲(chǔ)屬性擁有內(nèi)存——指定構(gòu)造器調(diào)用其父類構(gòu)造器執(zhí)行同樣操作——反復(fù)調(diào)用繼承樹直到頂端——直到頂端所有屬性存儲(chǔ)屬性有值之后撤卢,新實(shí)例內(nèi)存完全分配完成,第一階段結(jié)束
  • 第二階段:從上往下梧兼,依次給每個(gè)指定構(gòu)造器機(jī)會(huì)定制實(shí)例放吩,更改屬性并調(diào)用實(shí)例方法,直到低端
  • 指定構(gòu)造器都在第一階段羽杰,在便利構(gòu)造器調(diào)用完指定構(gòu)造器后可以修改變量渡紫,這部分是第二階段,如下
    class Student {
        var name = "xiaoming"
        var old: String
        init() {
    //        print("\(self.name)")  第一階段未結(jié)束考赛,實(shí)例未初始化完成惕澎,讀取self會(huì)導(dǎo)致error
            self.old = "16" //寫入賦值可以 在指定構(gòu)造器中設(shè)置默認(rèn)值
        }
        convenience init(old: String) {
            self.init()
            //至此,第一階段結(jié)束
            print("\(self.name)") //進(jìn)入第二階段颜骤,可以讀取self唧喉,此后為靈活處理屬性的地方
            //在便利構(gòu)造器中定義個(gè)性值
            self.old = old
        }
    }
    
  • swift中子類不繼承父類的構(gòu)造方法
  • 關(guān)于構(gòu)造器繼承的兩個(gè)規(guī)則
    1.如果子類沒有定義任何指定構(gòu)造器,則自動(dòng)繼承父類所有指定構(gòu)造器
    2.如果子類實(shí)現(xiàn)了所有父類中的指定構(gòu)造器忍抽,無(wú)論是自己定義還是由1繼承的八孝,那么子類會(huì)繼承所有父類的便利構(gòu)造器
  • 使用override重載父類構(gòu)造方法,當(dāng)子類存在和父類方法名相同的方法時(shí)必須要有Override鸠项,否則會(huì)報(bào)錯(cuò)
    class Bicyle: Vehicle {
        override init() {
            super.init()
            //至此第一階段結(jié)束干跛,子類有機(jī)會(huì)重寫初始化值
            self.numberOfWheels = 2
        }
    }
    
  • 使用?表示可失敗構(gòu)造器,防止必要參數(shù)缺失時(shí)錯(cuò)誤的成功創(chuàng)建實(shí)例
  • 嚴(yán)格說(shuō)構(gòu)造方法不返回實(shí)例祟绊,只是確保self在使用的時(shí)候被初始化完成楼入,所以對(duì)于可失敗構(gòu)造器來(lái)說(shuō),失敗返回nil牧抽,成功不用返回
    struct Animal {
        let species: String
        init?(species: String){
            if species.isEmpty { return nil }
            self.species = species
        }
    }
    
  • 枚舉為原值自動(dòng)提供可失敗初始化方式
  • 使用可失敗構(gòu)造器調(diào)用自身或父類的另一個(gè)可失敗構(gòu)造器嘉熊,可以使用新的可失敗構(gòu)造器在原可失敗構(gòu)造器上添加額外的失敗情況
    class Product {
        let name: String
        init?(name: String) {
            if name.isEmpty{ return nil }
            self.name = name
        }
    }
    class cartItem: Product {
        let quantity: Int
        init?(name: String, quantity: Int) {
            if quantity < 1 { return nil }
            self.quantity = quantity
            super.init(name: name)
        }  
    }
    
  • 可使用不可失敗構(gòu)造器調(diào)用失敗構(gòu)造器,在其中給予失敗條件固定值阎姥,并使用记舆!對(duì)于確定不會(huì)失敗的可失敗構(gòu)造器進(jìn)行強(qiáng)制拆包
    class Document {
        var name: String?
        init() {
          
        }
        init?(name: String) {
            if name.isEmpty { return nil }
            self.name = name
        }
    }
    class AutomaticallyNamedDocument: Document {
        override init() {
            super.init()
            self.name = "[Untitled]"
        }
        override init?(name: String) {
            super.init()
            if name.isEmpty {
                self.name = "[Untitled]"
            } else {
                self.name = name
            }
        }
    }
    class UntitledDocument: Document {
        override init() {
            super.init(name: "[Untitled]")!
        }
    }
    
  • 使用required關(guān)鍵字來(lái)表示必備構(gòu)造器,子類也必須實(shí)現(xiàn)呼巴,不需要override關(guān)鍵字而是繼續(xù)使用required
  • 使用閉包給函數(shù)屬性賦予初始值泽腮,注意閉包內(nèi)類本身沒有構(gòu)造完成,所以不能在閉包函數(shù)內(nèi)調(diào)用其他類屬性(即使屬性有默認(rèn)值)衣赶,不能在閉包內(nèi)使用self诊赊,不能在閉包內(nèi)調(diào)用其他類中函數(shù)。實(shí)際上就是給某些相對(duì)復(fù)雜的屬性使用一個(gè)新的匿名函數(shù)賦值府瞄,而由于新的匿名函數(shù)沒有參數(shù)碧磅,所以不能使用匿名函數(shù)外的變量碘箍。
    struct Chessboard {
      let boardColors: [Bool] = {
          var temporaryBoard = [Bool]()
          var isBlack = false
          for i in 1...8 {
              for j in 1...8 {
                  temporaryBoard.append(isBlack)
                  isBlack = !isBlack
              }
              isBlack = !isBlack
          }
          return temporaryBoard
      }()
      func squareIsBlckAt(row: Int, column: Int) -> Bool {
          return boardColors[(row * 8) + column]
      }
    }
    
代碼示例

函數(shù)繼承樹關(guān)于構(gòu)造器的繼承以及指定構(gòu)造器和便利構(gòu)造器的應(yīng)用。

class Food {
    var name: String
    init(name: String) {
        self.name = name
    }
    //提供一個(gè)帶有默認(rèn)值的便利構(gòu)造器
    convenience init() {
        self.init(name: "[Unnamed]]")
    }
}

let namedMeat = Food.init(name: "Bacon")

class RecipeIngredient: Food {
    var quantity: Int
    init(name: String, quantity: Int) {
        //本類中的屬性可以在super.init前面賦值鲸郊,而父類的屬性要在super.init后賦值
        self.quantity = quantity
        super.init(name: name)
    }
    //提供一個(gè)便利構(gòu)造器不指定個(gè)數(shù)時(shí)默認(rèn)為1
    //此方法實(shí)際上重載的是food中的指定構(gòu)造器
    override convenience init(name: String) {
        self.init(name: name, quantity: 1)
    }
    //和父類中的便利構(gòu)造器相同丰榴,但是不需要override重載
    convenience init() {
        self.init(name: "default", quantity: 0)
    }
}

let oneMysteryItem = RecipeIngredient()
let oneBacon = RecipeIngredient.init(name: "Bacon")
let sixEggs = RecipeIngredient.init(name: "Eggs", quantity: 6)

class AShoppingListItem: RecipeIngredient {
    var purchased = false
    // 使用閉包返回一個(gè)只讀計(jì)算屬性
    var description: String {
        var output = "\(quantity) x \(name) "
        output += purchased ? "??" : "?"
        return output
    }
}

var breakfaseList = [AShoppingListItem(), AShoppingListItem.init(name: "Bacon"), AShoppingListItem.init(name: "Eggs", quantity: 6)]
breakfaseList[0].name = "Orange juice"
breakfaseList[0].purchased = true
for item in breakfaseList {
    print("\(item.description)")
}
補(bǔ)充幾點(diǎn)
  • 方法名,參數(shù)個(gè)數(shù)秆撮,參數(shù)名完全相同的方法才算是一個(gè)方法四濒,才需要用Override重載
  • 使用convenience定義的構(gòu)造器一定要調(diào)用指定構(gòu)造器,否則會(huì)報(bào)錯(cuò)
  • 如果子類中定義的convenience構(gòu)造器有和父類中的某個(gè)指定構(gòu)造器方法重疊职辨,也需要使用override重載
  • 如果子類中定義的convenience構(gòu)造器于父類中某個(gè)convenience方法相同盗蟆,不需要使用override重載
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市舒裤,隨后出現(xiàn)的幾起案子喳资,更是在濱河造成了極大的恐慌,老刑警劉巖腾供,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仆邓,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡台腥,警方通過(guò)查閱死者的電腦和手機(jī)宏赘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)黎侈,“玉大人,你說(shuō)我怎么就攤上這事闷游【海” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵脐往,是天一觀的道長(zhǎng)休吠。 經(jīng)常有香客問(wèn)我,道長(zhǎng)业簿,這世上最難降的妖魔是什么瘤礁? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任钳幅,我火速辦了婚禮廉邑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘炒俱。我一直安慰自己巷燥,他們只是感情好赡盘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缰揪,像睡著了一般陨享。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天抛姑,我揣著相機(jī)與錄音赞厕,去河邊找鬼。 笑死定硝,一個(gè)胖子當(dāng)著我的面吹牛皿桑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播喷斋,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼唁毒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了星爪?” 一聲冷哼從身側(cè)響起浆西,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎顽腾,沒想到半個(gè)月后近零,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抄肖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年久信,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漓摩。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡裙士,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出管毙,到底是詐尸還是另有隱情腿椎,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布夭咬,位于F島的核電站啃炸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏卓舵。R本人自食惡果不足惜南用,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掏湾。 院中可真熱鬧裹虫,春花似錦、人聲如沸忘巧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)砚嘴。三九已至十酣,卻和暖如春涩拙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背耸采。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工兴泥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人虾宇。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓搓彻,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親嘱朽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子旭贬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 簡(jiǎn)介 *自定義構(gòu)造過(guò)程 *默認(rèn)構(gòu)造器 *值類型的構(gòu)造器代理 *類的繼承和構(gòu)造過(guò)程 *可失敗構(gòu)造器 *必需構(gòu)造器 *...
    FishSha閱讀 270評(píng)論 0 0
  • 20- 枚舉,枚舉原始值,枚舉相關(guān)值,switch提取枚舉關(guān)聯(lián)值 Swift枚舉: Swift中的枚舉比OC中的枚...
    iOS_恒仔閱讀 2,278評(píng)論 1 6
  • ?構(gòu)造過(guò)程是使用類、結(jié)構(gòu)體或枚舉類型一個(gè)實(shí)例的準(zhǔn)備過(guò)程搪泳。在新實(shí)例可用前必須執(zhí)行這個(gè)過(guò)程稀轨,具體操作包括設(shè)置實(shí)例中每個(gè)...
    EndEvent閱讀 632評(píng)論 0 3
  • 123.繼承 一個(gè)類可以從另外一個(gè)類繼承方法,屬性和其他特征。當(dāng)一個(gè)類繼承另外一個(gè)類時(shí), 繼承類叫子類, 被繼承的...
    無(wú)灃閱讀 1,392評(píng)論 2 4
  • 1.1-首先談一下什么是CoreData? coreData是ios5之后蘋果原生用于對(duì)象數(shù)據(jù)管理并且持久化(存儲(chǔ)...
    wangwei_1916閱讀 499評(píng)論 0 3