Swift3.0 - 初始化和釋放

Swift3.0 - 真的很簡單
Swift3.0 - 數(shù)據(jù)類型
Swift3.0 - Array
Swift3.0 - 字典
Swift3.0 - 可選值
Swift3.0 - 集合
Swift3.0 - 流控制
Swift3.0 - 對象和類
Swift3.0 - 屬性
Swift3.0 - 函數(shù)和閉包
Swift3.0 - 初始化和釋放
Swift3.0 - 協(xié)議protocol
Swift3.0 - 類和結構體的區(qū)別
Swift3.0 - 枚舉
Swift3.0 - 擴展
Swift3.0 - 下標
Swift3.0 - 泛型
Swift3.0 - 異常錯誤
Swift3.0 - 斷言
Swift3.0 - 自動引用計數(shù)(strong,weak,unowned)
Swift3.0 - 檢測API
Swift3.0 - 對象的標識
Swift3.0 - 注釋
Swift3.0 - 元類型
Swift3.0 - 空間命名
Swift3.0 - 對象判等
Swift3.0 - 探究Self的用途
Swift3.0 - 類簇
Swift3.0 - 動態(tài)調(diào)用對象(實例)方法
Swift3.0 - 文本輸出
Swift3.0 - 黑魔法swizzle
Swift3.0 - 鏡像
Swift3.0 - 遇到的坑

注意

1.系統(tǒng)要求存儲屬性必須初始化
2.可選值可以不用初始化,如果不初始化值,系統(tǒng)默認用nil初始化它
3.如果非可選類型存儲屬性不設置默認值,則必須在初始化方法中對其進行初始化
4.類必須自己寫初始化方法,初始化沒有默認值的非可選存儲屬性
5.結構體系統(tǒng)默認會添加初始化方法,當然自己也可以自定義
6.子類如果沒有自己的初始化方法,系統(tǒng)默認使用父類的初始化方法,一旦有了自己的初始化方法,或者重寫了父類的初始化方法,則父類的所有初始化不能被子類調(diào)用
7.你可以給子類添加和父類相同的初始化方法,但需要加上override 修飾
8.重寫父類的convenience修飾的方便初始化方法,不需要加override 關鍵字

  • 指定初始化(Designated)

1.可以有多個指定初始化方法

class Person{
var name:String
var age:Int = 0
var weight:Double = 0.0
var height:Double = 0.0
init(name:String,height:Double) {
    self.name = name
    self.height = height
}
init(name:String) {
    self.name = name
}
}
  • 方便初始化(convenience)

記住:

1.在同一個類,使用convenience修飾的初始化方法必須調(diào)用一個其他初始化方法
2.convenience 必須最終調(diào)用一個指定的初始化方法
3.當子類繼承父類時,子類的初始化方法,必須調(diào)用父類的指定初始化方法,不能調(diào)用使用convienience修飾的方便初始化方法
4.在swift3.0 初始化中,可以自己調(diào)用自己的初始化方法,系統(tǒng)不會檢測出來,在創(chuàng)建convenience方便初始化方法的時候,需要小心,千萬不要相互引用了

看圖理解更透徹

實例代碼

// 父類
class Person{
    var name:String
    var age:Int = 0
    var weight:Double = 0.0
    var height:Double = 0.0
    init(name:String,height:Double) {
        self.name = name
        self.height = height
    }
    init(name:String) {
        self.name = name
    }
    // 1.定義一個convenience 修飾的初始化方法,如果在同一個類中必須 調(diào)用其他沒有convenience修飾的初始化方法
    convenience init(name:String,age:Int){
        self.init(name:name)
        self.age = age
    }
    // 2.如果定義兩個或者多個convenience 修飾的初始化,只需要調(diào)用任意一個初始化方法即可滿足語法要求
    convenience init(name:String,age:Int,weight:Double){
        self.init(name:name,age:age)
        self.weight = weight
    }
}
// 子類
class Man: Person {
    var address:String = ""
    init(name:String,age:Int,weight:Double) {
         // 3.必須調(diào)用父類指定初始化方法,不能調(diào)用convenience 修飾的方便初始化方法
         super.init(name: name)
    } 
}
看完代碼這種圖就好理解了
  • 類初始化的過程

第一階段

1.調(diào)用指定初始化方法或者方便初始化
2.給新的實例分配內(nèi)存,但內(nèi)存還沒有初始化
3.指定初始化方法確定所有存儲屬性都被初始化,內(nèi)存這個時候被初始化
4.然后去調(diào)用父類的指定初始化方法,任務和調(diào)用自己指定初始化方法相同
5.繼續(xù)在類繼承鏈中指定上述過程,直到達到鏈的頂部為止
6.當?shù)酵瓿苫惖某跏蓟臅r候,實例的初始化算是完成了,我們的第一階段完成

第二階段

1.可以對屬性值進行修改
2.可以調(diào)用對象方法

  • 重寫初始化方法

先看一個例子

// 父類
class Person{
    var name:String
    var age:Int = 0
    var weight:Double = 0.0
    var height:Double = 0.0
    init(name:String,height:Double) {
        self.name = name
        self.height = height
    }
    init(name:String) {
        self.name = name
    }
    convenience init(name:String,age:Int,weight:Double){
        self.init(name:name)
        self.age = age
        self.weight = weight
    }
}
 // 子類
  class Man: Person {
var address:String = ""

   // 重寫父類指定初始化方法
    override init(name:String) {
        super.init(name: name)
    }
    // 重寫父類convenience 修飾的初始化方法 不需要添加override 關鍵字
     init(name:String,age:Int,weight:Double){
        super.init(name: name)
    }
    // 創(chuàng)建自己的初始化方法
    convenience      init(name:String,age:Int,weight:Double,address:String){
        self.init(name: name)
        self.address = address
        self.age = age
        self.weight = weight
    }  
}

總結:

1.創(chuàng)建新的指定初始化方法,必須調(diào)用父類的指定初始化方法 (Designated)
2.創(chuàng)建新的方便初始化方法,必須調(diào)用自己的指定初始化方法,或者方便初始化方法(convenience)
3.重寫父類的指定初始化方法,在方法名前加override ,然后調(diào)用父類的指定初始化方法
4.重寫父類的方便初始化方法(convenience) 不需要加override 或者convenience 關鍵字,調(diào)用父類的指定初始化方法,如果加上convenice關鍵字,則必須調(diào)用自己的初始化方法
5.如果子類沒有初始化方法,系統(tǒng)會自動繼承父類的初始化方法
6.初始化調(diào)用父類初始化時,需要先初始化子類的存儲屬性,但是如果是convenience修飾的初始化方法,要先調(diào)用自己的其他初始化方法,然后再給自己的存儲屬性賦值

  • 創(chuàng)建一個可能失敗的初始化方法

注意:

1.不能在重寫的初始化方法改為可能失敗的初始化方法
2.不能使用相同的參數(shù)定義一個可能失敗的初始化方法和不會失敗的初始化方法
3.可能失敗的類型可以重寫為不會失敗類型
4.init? 可以被重寫為init!,當然可逆也是可以的
5.init?和init! 都可以被重寫為init

例子1

class Man: Person {
    var address:String = ""
    convenience  init?(name:String,age:Int,weight:Double,address:String){
    if name == "" {
        return nil
    }
    self.init(name: name)
    self.address = address
    self.age = age
    self.weight = weight
    }
}

例子2

enum TemperatureUnit {
    case kelvin, celsius, fahrenheit
    init?(symbol: Character) {
        switch symbol {
       case "K":
            self = .kelvin
        case "C":
            self = .celsius
        case "F":
            self = .fahrenheit
        default:
            return nil
        }
    }
}

例子2: 子類將父類可能失敗的初始化方法,修改為不會失敗的類型

class Animal{
    var name:String
    init?(name:String) {
        if name.isEmpty {
            return nil
        }
        self.name = name
    }
}

對于可能出現(xiàn)空值的對象或者其他類型,在使用之前必須進行驗證

enum TemperatureUnit: Character {
case kelvin = "K", celsius = "C", fahrenheit = "F"
}

let fahrenheitUnit = TemperatureUnit(rawValue: "F")
if fahrenheitUnit != nil {
    print("This is a defined temperature unit, so initialization     succeeded.")
}

需求: 創(chuàng)建一個文件類,文件名字可以為nil,但是不能為空即""

寫法一:

class Document {
    var name:String?
    init?(name:String?){
        if name != nil && name!.isEmpty{
            return nil
        }
        self.name = name
    }
}

分析這種寫法

只有一種初始化方法,也就是說,不管有沒有名字,我們都需要給初始化傳個參數(shù),顯然這樣不合理,目標不明確

寫法二:

class Document {
var name: String?
init() {} // 專門初始化name為 nil的情況 
init?(name: String) { // 傳入名字 ,肯定不為nil ,只需要判斷是否為空即可
    if name.isEmpty { return nil }
    self.name = name
}
}

疑問: init! 和init? 被重寫為init 的意義何在?

暫時沒想到

  • 需要的初始化方法(required)
    注意

1.子類必須重寫父類用required修飾的方法
2.可以和convenience 組合使用

a-1.父類要求一個初始化方法被重寫

class Person{
    var name:String
    var age:Int = 0
    var weight:Double = 0.0
    var height:Double = 0.0
    init(name:String,height:Double) {
        self.name = name
        self.height = height
    }
    init(name:String) {
        self.name = name
    }
   // 要求子類必須重寫這個方法
   required convenience init(name:String,age:Int,weight:Double){
        self.init(name:name)
        self.age = age
        self.weight = weight
    }
}

a-2.子類重寫父類要求的初始化方法

class Man: Person {
    var address:String = ""
    // 重寫父類要求的初始化convenience 修飾的初始化方法 不需要添加override 關鍵字
    required init(name:String,age:Int,weight:Double){
    super.init(name: name)
   }
}
  • 反初始化(deinit)

注意:

1.deinit 在對象被釋放前調(diào)用

寫法很簡單

deinit {
}

蘋果文檔有個例子簡單講解了一下它的重要性
例子: 有一個賭徒在銀行存了10_000 元,賭徒從銀行取錢然后去賭博,當賭徒對象釋放了就將錢全部存到銀行

class Bank {
    static var coinsInBank = 10_000
    static func distribute(coins numberOfCoinsRequested: Int) -> Int {
        let numberOfCoinsToVend = min(numberOfCoinsRequested, coinsInBank)
        coinsInBank -= numberOfCoinsToVend
        return numberOfCoinsToVend
    }
    static func receive(coins: Int) {
        coinsInBank += coins
    }
}

賭徒類

class Player {
    var coinsInPurse: Int
    init(coins: Int) {
        coinsInPurse = Bank.distribute(coins: coins)
  }
   func win(coins: Int) {
        coinsInPurse += Bank.distribute(coins: coins)
   }
  deinit {
        Bank.receive(coins: coinsInPurse)
    }
}

執(zhí)行

var playerOne: Player? = Player(coins: 100)
playerOne!.win(coins: 2_000)
playerOne = nil
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,772評論 3 422
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,947評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,201評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,960評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,350評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,549評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,104評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,914評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,089評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,340評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,753評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,007評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,834評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,106評論 2 375

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

  • 官方文檔 初始化 Initialization是為準備使用類,結構體或者枚舉實例的一個過程。這個過程涉及了在實例里...
    hrscy閱讀 1,146評論 0 1
  • 初始化 (Initialization) 自從蘋果2014年發(fā)布Swift,到現(xiàn)在已經(jīng)兩年多了,而Swift也來到...
    Lebron_James閱讀 1,216評論 0 0
  • 初始化(Initialization) 初始化是類、結構體、枚舉類型的準備過程。這個過程涉及到所有存儲屬性的初始化...
    泗哥閱讀 5,647評論 0 3
  • #幸福是需要修出來的~每天進步1%~幸福實修08班~04-姜群-富陽# 20170629(11/99) 【幸福三朵...
    呼哈二姐閱讀 211評論 1 1
  • 今天用兩句趙孟頫《松雪齋書論》中的話來作個引子——學書有二:一曰筆法,二曰字形。筆法弗精,雖善猶惡;字形弗妙,雖熟...
    一只笨蛋閱讀 925評論 4 6