Swift語法總結(jié)-繼承,構(gòu)造函數(shù),析構(gòu)函數(shù)

1. 繼承

一個類可以繼承另一個類的方法,屬性和其它特性。當一個類繼承其它類時,繼承類叫子類,被繼承類叫超類(或父類)。在 Swift 中,繼承是區(qū)分「類」與其它類型的一個基本特征。

可以為類中繼承來的屬性添加屬性觀察器,這樣一來,當屬性值改變時,類就會被通知到??梢詾槿魏螌傩蕴砑訉傩杂^察器,無論它原本被定義為存儲型屬性還是計算型屬性。

1.1.1 定義一個基類

不繼承于其它類的類,稱之為基類。

注意
Swift 中的類并不是從一個通用的基類繼承而來。如果你不為你定義的類指定一個超類的話,這個類就自動成為基類。

1.1.2 子類生成

子類生成指的是在一個已有類的基礎(chǔ)上創(chuàng)建一個新的類。子類繼承超類的特性,并且可以進一步完善。你還可以為子類添加新的特性。

為了指明某個類的超類,將超類名寫在子類名的后面,用冒號分隔:

class SomeClass: SomeSuperclass {
    // 這里是子類的定義
}
1.2 重寫

子類可以為繼承來的實例方法,類方法,實例屬性,或下標提供自己定制的實現(xiàn)。我們把這種行為叫重寫。

如果要重寫某個特性,你需要在重寫定義的前面加上override 關(guān)鍵字。這么做,你就表明了你是想提供一個重寫版本,而非錯誤地提供了一個相同的定義。

override 關(guān)鍵字會提醒 Swift 編譯器去檢查該類的超類(或其中一個父類)是否有匹配重寫版本的聲明。這個檢查可以確保你的重寫定義是正確的。

1.2.1 訪問超類的方法,屬性及下標

當你在子類中重寫超類的方法,屬性或下標時,有時在你的重寫版本中使用已經(jīng)存在的超類實現(xiàn)會大有裨益。比如,你可以完善已有實現(xiàn)的行為,或在一個繼承來的變量中存儲一個修改過的值。

在合適的地方,你可以通過使用super 前綴來訪問超類版本的方法,屬性或下標:

? 在方法someMethod() 的重寫實現(xiàn)中,可以通過super.someMethod() 來調(diào)用超類版本的someMethod() 方法。
? 在屬性someProperty 的 getter 或 setter 的重寫實現(xiàn)中,可以通過super.someProperty 來訪問超類版本的someProperty 屬性。
? 在下標的重寫實現(xiàn)中,可以通過super[someIndex] 來訪問超類版本中的相同下標。

1.2.2 重寫方法

在子類中,你可以重寫繼承來的實例方法或類方法,提供一個定制或替代的方法實現(xiàn)。

class Train: Vehicle {
    override func makeNoise() {
        print("Choo Choo")
    }
}
1.2.3 重寫屬性

你可以重寫繼承來的實例屬性或類型屬性,提供自己定制的 getter 和 setter,或添加屬性觀察器使重寫的屬性可以觀察屬性值什么時候發(fā)生改變。

1.2.3.1 重寫屬性的 Getters 和 Setters

你可以提供定制的 getter(或 setter)來重寫任意繼承來的屬性,無論繼承來的屬性是存儲型的還是計算型的屬性。子類并不知道繼承來的屬性是存儲型的還是計算型的,它只知道繼承來的屬性會有一個名字和類型。你在重寫一個屬性時,必需將它的名字和類型都寫出來。這樣才能使編譯器去檢查你重寫的屬性是與超類中同名同類型的屬性相匹配的。

你可以將一個繼承來的只讀屬性重寫為一個讀寫屬性,只需要在重寫版本的屬性里提供 getter 和 setter 即可。但是,你不可以將一個繼承來的讀寫屬性重寫為一個只讀屬性。

注意
如果你在重寫屬性中提供了 setter,那么你也一定要提供 getter。如果你不想在重寫版本中的 getter 里修改繼承來的屬性值,你可以直接通過super.someProperty 來返回繼承來的值,其中someProperty 是你要重寫的屬性的名字。

1.2.3.2 重寫屬性觀察器

你可以通過重寫屬性為一個繼承來的屬性添加屬性觀察器。這樣一來,當繼承來的屬性值發(fā)生改變時,你就會被通知到,無論那個屬性原本是如何實現(xiàn)的

注意
<1>你不可以為繼承來的常量存儲型屬性或繼承來的只讀計算型屬性添加屬性觀察器。這些屬性的值是不可以被設(shè)置的,所以,為它們提供willSet 或didSet 實現(xiàn)是不恰當。
<2>此外還要注意,你不可以同時提供重寫的 setter 和重寫的屬性觀察器。如果你想觀察屬性值的變化,并且你已經(jīng)為那個屬性提供了定制的 setter,那么你在 setter 中就可以觀察到任何值變化了。

1.2.4 防止重寫

你可以通過把方法,屬性或下標標記為final 來防止它們被重寫,只需要在聲明關(guān)鍵字前加上final 修飾符即可

如果你重寫了帶有final 標記的方法,屬性或下標,在編譯時會報錯。在類擴展中的方法,屬性或下標也可以在擴展的定義里標記為 final 的。

你可以通過在關(guān)鍵字class 前添加final 修飾符( final class )來將整個類標記為 final 的。這樣的類是不可被繼承的,試圖繼承這樣的類會導致編譯報錯。

2. 構(gòu)造過程

構(gòu)造過程是使用類、結(jié)構(gòu)體或枚舉類型的實例之前的準備過程。在新實例可用前必須執(zhí)行這個過程,具體操作包括設(shè)置實例中每個存儲型屬性的初始值和執(zhí)行其他必須的設(shè)置或初始化工作。

2.1 存儲屬性的初始賦值

類和結(jié)構(gòu)體在創(chuàng)建實例時,必須為所有存儲型屬性設(shè)置合適的初始值。存儲型屬性的值不能處于一個未知的狀態(tài)。你可以在構(gòu)造器中為存儲型屬性賦初值,也可以在定義屬性時為其設(shè)置默認值。

注意
當你為存儲型屬性設(shè)置默認值或者在構(gòu)造器中為其賦值時,它們的值是被直接設(shè)置的,不會觸發(fā)任何屬性觀察者。

2.1.1 構(gòu)造器

構(gòu)造器在創(chuàng)建某個特定類型的新實例時被調(diào)用。它的最簡形式類似于一個不帶任何參數(shù)的實例方法,以關(guān)鍵字init 命名:

init() {
    // 在此處執(zhí)行構(gòu)造過程
}
2.1.2 默認屬性值

可以在構(gòu)造器中為存儲型屬性設(shè)置初始值。同樣,你也可以在屬性聲明時為其設(shè)置默認值。

注意:如果一個屬性總是使用相同的初始值,那么為其設(shè)置一個默認值比每次都在構(gòu)造器中賦值要好。兩種方法的效果是一樣的,只不過使用默認值讓屬性的初始化和聲明結(jié)合得更緊密。使用默認值能讓你的構(gòu)造器更簡潔、更清晰,且能通過默認值自動推導出屬性的類型;同時,它也能讓你充分利用默認構(gòu)造器、構(gòu)造器繼承等特性

2.2 自定義構(gòu)造過程

可以通過輸入?yún)?shù)和可選類型的屬性來自定義構(gòu)造過程,也可以在構(gòu)造過程中修改常量屬性。

2.2.1 構(gòu)造參數(shù)

自定義構(gòu)造過程時,可以在定義中提供構(gòu)造參數(shù),指定所需值的類型和名字。構(gòu)造參數(shù)的功能和語法跟函數(shù)和方法的參數(shù)相同。

struct Celsius {
    var temperatureInCelsius: Double
    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
}
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius 是 100.0
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius 是 0.0
2.2.2 參數(shù)的內(nèi)部名稱和外部名稱

跟函數(shù)和方法參數(shù)相同,構(gòu)造參數(shù)也擁有一個在構(gòu)造器內(nèi)部使用的參數(shù)名字和一個在調(diào)用構(gòu)造器時使用的外部參數(shù)名字。

然而,構(gòu)造器并不像函數(shù)和方法那樣在括號前有一個可辨別的名字。因此在調(diào)用構(gòu)造器時,主要通過構(gòu)造器中的參數(shù)名和類型來確定應該被調(diào)用的構(gòu)造器。正因為參數(shù)如此重要,如果你在定義構(gòu)造器時沒有提供參數(shù)的外部名字,Swift 會為構(gòu)造器的每個參數(shù)自動生成一個跟內(nèi)部名字相同的外部名。

struct Color {
    let red, green, blue: Double
    init(red: Double, green: Double, blue: Double) {
        self.red = red
        self.green = green
        self.blue = blue
    }
    init(white: Double) {
        red = white
        green = white
        blue = white
    }
}
//兩種構(gòu)造器都能用于創(chuàng)建一個新的Color 實例,你需要為構(gòu)造器每個外部參數(shù)傳值:
let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)
let halfGray = Color(white: 0.5)
2.2.3 不帶外部名的構(gòu)造器參數(shù)

如果你不希望為構(gòu)造器的某個參數(shù)提供外部名字,你可以使用下劃線( _ )來顯式描述它的外部名,以此重寫上面所說的默認行為。

struct Celsius {
    var temperatureInCelsius: Double
        init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
    init(_ celsius: Double){
        temperatureInCelsius = celsius
    }
}
let bodyTemperature = Celsius(37.0)
// bodyTemperature.temperatureInCelsius 為 37.0
2.2.4 可選屬性類型

如果你定制的類型包含一個邏輯上允許取值為空的存儲型屬性——無論是因為它無法在初始化時賦值,還是因為它在之后某個時間點可以賦值為空——你都需要將它定義為可選類型??蛇x類型的屬性將自動初始化為nil ,表示這個屬性是有意在初始化時設(shè)置為空的。

class SurveyQuestion {
    var text: String
    var response: String?
    init(text: String) {
        self.text = text
    }
    func ask() {
        print(text)
    }
}
2.2.5 構(gòu)造過程中常量屬性的修改

你可以在構(gòu)造過程中的任意時間點給常量屬性指定一個值,只要在構(gòu)造過程結(jié)束時是一個確定的值。一旦常量屬性被賦值,它將永遠不可更改。

注意
對于類的實例來說,它的常量屬性只能在定義它的類的構(gòu)造過程中修改;不能在子類中修改。

//盡管text 屬性現(xiàn)在是常量,我們?nèi)匀豢梢栽陬惖臉?gòu)造器中設(shè)置它的值
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()
// 打印 "How about beets?"
beetsQuestion.response = "I also like beets. (But not with cheese.)"
2.3 默認構(gòu)造器

如果結(jié)構(gòu)體或類的所有屬性都有默認值,同時沒有自定義的構(gòu)造器,那么 Swift 會給這些結(jié)構(gòu)體或類提供一個默認構(gòu)造器(default initializers)。這個默認構(gòu)造器將簡單地創(chuàng)建一個所有屬性值都設(shè)置為默認值的實例。

class ShoppingListItem {
    var name: String?
    var quantity = 1
    var purchased = false
}
var item = ShoppingListItem()
2.3.1 結(jié)構(gòu)體的逐一成員構(gòu)造器

如果結(jié)構(gòu)體沒有提供自定義的構(gòu)造器,它們將自動獲得一個逐一成員構(gòu)造器,即使結(jié)構(gòu)體的存儲型屬性沒有默認值。

struct Size {
    var width = 0.0, height = 0.0
}
let twoByTwo = Size(width: 2.0, height: 2.0)
2.3.2 值類型的構(gòu)造器代理

構(gòu)造器可以通過調(diào)用其它構(gòu)造器來完成實例的部分構(gòu)造過程。這一過程稱為構(gòu)造器代理,它能減少多個構(gòu)造器間的代碼重復。

對于值類型,你可以使用self.init 在自定義的構(gòu)造器中引用相同類型中的其它構(gòu)造器。并且你只能在構(gòu)造器內(nèi)部調(diào)用self.init 。

注意
假如你希望默認構(gòu)造器、逐一成員構(gòu)造器以及你自己的自定義構(gòu)造器都能用來創(chuàng)建實例,可以將自定義的構(gòu)造器寫到擴展( extension )中,而不是寫在值類型的原始定義中

2.4 類的繼承和構(gòu)造過程

類里面的所有存儲型屬性——包括所有繼承自父類的屬性——都必須在構(gòu)造過程中設(shè)置初始值。Swift 為類類型提供了兩種構(gòu)造器來確保實例中所有存儲型屬性都能獲得初始值,它們分別是指定構(gòu)造器和便利構(gòu)造器。

2.4.1.1 指定構(gòu)造器和便利構(gòu)造器

指定構(gòu)造器是類中最主要的構(gòu)造器。一個指定構(gòu)造器將初始化類中提供的所有屬性,并根據(jù)父類鏈往上調(diào)用父類的構(gòu)造器來實現(xiàn)父類的初始化。

2.4.1.2 指定構(gòu)造器和便利構(gòu)造器的語法

類的指定構(gòu)造器的寫法跟值類型簡單構(gòu)造器一樣:

init(parameters) {
    statements
}

便利構(gòu)造器也采用相同樣式的寫法,但需要在init 關(guān)鍵字之前放置convenience 關(guān)鍵字,并使用空格將它們倆分開:

convenience init(parameters) {
    statements
}
2.4.1.3 類的構(gòu)造器代理規(guī)則

規(guī)則 1 - 指定構(gòu)造器必須調(diào)用其直接父類的的指定構(gòu)造器。
規(guī)則 2 - 便利構(gòu)造器必須調(diào)用同類中定義的其它構(gòu)造器。
規(guī)則 3 - 便利構(gòu)造器必須最終導致一個指定構(gòu)造器被調(diào)用。

? 指定構(gòu)造器必須總是向上代理
? 便利構(gòu)造器必須總是橫向代理

2.4.1.4 兩段式構(gòu)造過程

Swift 中類的構(gòu)造過程包含兩個階段。第一個階段,每個存儲型屬性被引入它們的類指定一個初始值。當每個存儲型屬性的初始值被確定后,第二階段開始,它給每個類一次機會,在新實例準備使用之前進一步定制它們的存儲型屬性。

2.4.1.5 構(gòu)造器的繼承和重寫

跟 Objective-C 中的子類不同,Swift 中的子類默認情況下不會繼承父類的構(gòu)造器。Swift 的這種機制可以防止一個父類的簡單構(gòu)造器被一個更精細的子類繼承,并被錯誤地用來創(chuàng)建子類的實例。

注意:當你重寫一個父類的指定構(gòu)造器時,你總是需要寫override 修飾符,即使你的子類將父類的指定構(gòu)造器重寫為了便利構(gòu)造器。

class Vehicle {
    var numberOfWheels = 0
    var description: String {
        return "\(numberOfWheels) wheel(s)"
    }
}
class Bicycle: Vehicle {
    override init() {
        super.init()
        numberOfWheels = 2
    }
}

注意
子類可以在初始化時修改繼承來的變量屬性,但是不能修改繼承來的常量屬性。

2.4.1.6 構(gòu)造器的自動繼承

如上所述,子類在默認情況下不會繼承父類的構(gòu)造器。但是如果滿足特定條件,父類構(gòu)造器是可以被自動繼承的。在實踐中,這意味著對于許多常見場景你不必重寫父類的構(gòu)造器,并且可以在安全的情況下以最小的代價繼承父類的構(gòu)造器。

規(guī)則 1 - 如果子類沒有定義任何指定構(gòu)造器,它將自動繼承所有父類的指定構(gòu)造器。
規(guī)則 2 - 如果子類提供了所有父類指定構(gòu)造器的實現(xiàn)——無論是通過規(guī)則 1 繼承過來的,還是提供了自定義實現(xiàn)——它將自動繼承所有父類的便利構(gòu)造器。

2.5 可失敗構(gòu)造器

如果一個類、結(jié)構(gòu)體或枚舉類型的對象,在構(gòu)造過程中有可能失敗,則為其定義一個可失敗構(gòu)造器。這里所指的“失敗”是指,如給構(gòu)造器傳入無效的參數(shù)值,或缺少某種所需的外部資源,又或是不滿足某種必要的條件等。

為了妥善處理這種構(gòu)造過程中可能會失敗的情況。你可以在一個類,結(jié)構(gòu)體或是枚舉類型的定義中,添加一個或多個可失敗構(gòu)造器。其語法為在init 關(guān)鍵字后面添加問號( init? )。

注意
<1>可失敗構(gòu)造器的參數(shù)名和參數(shù)類型,不能與其它非可失敗構(gòu)造器的參數(shù)名,及其參數(shù)類型相同。
<2>嚴格來說,構(gòu)造器都不支持返回值。因為構(gòu)造器本身的作用,只是為了確保對象能被正確構(gòu)造。因此你只是用return nil 表明可失敗構(gòu)造器構(gòu)造失敗,而不要用關(guān)鍵字return 來表明構(gòu)造成功。

struct Animal {
    let species: String
    init?(species: String) {
        if species.isEmpty { return nil }
        self.species = species
    }
}

通過該可失敗構(gòu)造器來構(gòu)建一個Animal 的實例,并檢查構(gòu)造過程是否成功:

let someCreature = Animal(species: "Giraffe")
// someCreature 的類型是 Animal? 而不是 Animal
if let giraffe = someCreature {
    print("An animal was initialized with a species of \(giraffe.species)")
}
// 打印 "An animal was initialized with a species of Giraffe"

如果你給該可失敗構(gòu)造器傳入一個空字符串作為其參數(shù),則會導致構(gòu)造失?。?/p>

let anonymousCreature = Animal(species: "")
// anonymousCreature 的類型是 Animal?, 而不是 Animal
if anonymousCreature == nil {
    print("The anonymous creature could not be initialized")
}
// 打印 "The anonymous creature could not be initialized"
2.5.1 枚舉類型的可失敗構(gòu)造器

可以通過一個帶一個或多個參數(shù)的可失敗構(gòu)造器來獲取枚舉類型中特定的枚舉成員。如果提供的參數(shù)無法匹配任何枚舉成員,則構(gòu)造失敗。

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
            }
      }
}

利用該可失敗構(gòu)造器在三個枚舉成員中獲取一個相匹配的枚舉成員,當參數(shù)的值不能與任何枚舉成員相匹配時,則構(gòu)造失?。?/p>

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

let unknownUnit = TemperatureUnit(symbol: "X")
if unknownUnit == nil {
    print("This is not a defined temperature unit, so initialization failed.")
}
// 打印 "This is not a defined temperature unit, so initialization failed."
2.5.2 帶原始值的枚舉類型的可失敗構(gòu)造器

帶原始值的枚舉類型會自帶一個可失敗構(gòu)造器init?(rawValue:) ,該可失敗構(gòu)造器有一個名為rawValue 的參數(shù),其類型和枚舉類型的原始值類型一致,如果該參數(shù)的值能夠和某個枚舉成員的原始值匹配,則該構(gòu)造器會構(gòu)造相應的枚舉成員,否則構(gòu)造失敗。

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.")
}
// 打印 "This is a defined temperature unit, so initialization succeeded."

let unknownUnit = TemperatureUnit(rawValue: "X")
if unknownUnit == nil {
    print("This is not a defined temperature unit, so initialization failed.")
}
// 打印 "This is not a defined temperature unit, so initialization failed."
2.5.3 構(gòu)造失敗的傳遞

類,結(jié)構(gòu)體,枚舉的可失敗構(gòu)造器可以橫向代理到類型中的其他可失敗構(gòu)造器。類似的,子類的可失敗構(gòu)造器也能向上代理到父類的可失敗構(gòu)造器。

無論是向上代理還是橫向代理,如果你代理到的其他可失敗構(gòu)造器觸發(fā)構(gòu)造失敗,整個構(gòu)造過程將立即終止,接下來的任何構(gòu)造代碼不會再被執(zhí)行。

注意:可失敗構(gòu)造器也可以代理到其它的非可失敗構(gòu)造器。通過這種方式,你可以增加一個可能的失敗狀態(tài)到現(xiàn)有的構(gòu)造過程中。

2.5.4 重寫一個可失敗構(gòu)造器

如同其它的構(gòu)造器,你可以在子類中重寫父類的可失敗構(gòu)造器?;蛘吣阋部梢杂米宇惖姆强墒?gòu)造器重寫一個父類的可失敗構(gòu)造器。這使你可以定義一個不會構(gòu)造失敗的子類,即使父類的構(gòu)造器允許構(gòu)造失敗。

注意,當你用子類的非可失敗構(gòu)造器重寫父類的可失敗構(gòu)造器時,向上代理到父類的可失敗構(gòu)造器的唯一方式是對父類的可失敗構(gòu)造器的返回值進行強制解包。

注意
你可以用非可失敗構(gòu)造器重寫可失敗構(gòu)造器,但反過來卻不行。

2.5.5 可失敗構(gòu)造器 init!

通常來說我們通過在init 關(guān)鍵字后添加問號的方式( init? )來定義一個可失敗構(gòu)造器,但你也可以通過在init 后面添加驚嘆號的方式來定義一個可失敗構(gòu)造器( init! ),該可失敗構(gòu)造器將會構(gòu)建一個對應類型的隱式解包可選類型的對象。

2.6 必要構(gòu)造器

在類的構(gòu)造器前添加required 修飾符表明所有該類的子類都必須實現(xiàn)該構(gòu)造器:

class SomeClass {
    required init() {
        // 構(gòu)造器的實現(xiàn)代碼
    }
}

在子類重寫父類的必要構(gòu)造器時,必須在子類的構(gòu)造器前也添加required 修飾符,表明該構(gòu)造器要求也應用于繼承鏈后面的子類。在重寫父類中必要的指定構(gòu)造器時,不需要添加override 修飾符

class SomeSubclass: SomeClass {
    required init() {
        // 構(gòu)造器的實現(xiàn)代碼
    }
}

注意
如果子類繼承的構(gòu)造器能滿足必要構(gòu)造器的要求,則無須在子類中顯式提供必要構(gòu)造器的實現(xiàn)。

2.7 通過閉包或函數(shù)設(shè)置屬性的默認值

如果某個存儲型屬性的默認值需要一些定制或設(shè)置,你可以使用閉包或全局函數(shù)為其提供定制的默認值。每當某個屬性所在類型的新實例被創(chuàng)建時,對應的閉包或函數(shù)會被調(diào)用,而它們的返回值會當做默認值賦值給這個屬性。

class SomeClass {
    let someProperty: SomeType = {
        // 在這個閉包中給 someProperty 創(chuàng)建一個默認值
        // someValue 必須和 SomeType 類型相同
        return someValue
    }()
}

注意閉包結(jié)尾的大括號后面接了一對空的小括號。這用來告訴 Swift 立即執(zhí)行此閉包。如果你忽略了這對括號,相當于將閉包本身作為值賦值給了屬性,而不是將閉包的返回值賦值給屬性。

注意
如果你使用閉包來初始化屬性,請記住在閉包執(zhí)行時,實例的其它部分都還沒有初始化。這意味著你不能在閉包里訪問其它屬性,即使這些屬性有默認值。同樣,你也不能使用隱式的self 屬性,或者調(diào)用任何實例方法。

3. 析構(gòu)過程

析構(gòu)器只適用于類類型,當一個類的實例被釋放之前,析構(gòu)器會被立即調(diào)用。析構(gòu)器用關(guān)鍵字deinit 來標示,類似于構(gòu)造器要用init 來標示。

3.1 析構(gòu)過程原理

Swift 會自動釋放不再需要的實例以釋放資源,Swift 通過自動引用計數(shù)(ARC) 處理實例的內(nèi)存管理。通常當你的實例被釋放時不需要手動地去清理。但是,當使用自己的資源時,你可能需要進行一些額外的清理。

在類的定義中,每個類最多只能有一個析構(gòu)器,而且析構(gòu)器不帶任何參數(shù)

deinit {
    // 執(zhí)行析構(gòu)過程
}

析構(gòu)器是在實例釋放發(fā)生前被自動調(diào)用。你不能主動調(diào)用析構(gòu)器。子類繼承了父類的析構(gòu)器,并且在子類析構(gòu)器實現(xiàn)的最后,父類的析構(gòu)器會被自動調(diào)用。即使子類沒有提供自己的析構(gòu)器,父類的析構(gòu)器也同樣會被調(diào)用。

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

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