iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 22
0

反初始化

在 class 的實例被釋放的時候,反初始化器就會立即被調用。你可以用 deinit 關鍵字來寫反初始化器,反初始化器只在類類型中有效。


反初始化器原理

當你的實例不在需要時,Swift 會將其自動釋放,節省資源。 Swift 透過自動引用計數 (ARC) 處理實例的內存管理。通常,當你的實例被釋放時,你不需執行手動清理。通常,當你在使用自己的資源時,可能還是需要執行一些額外的清理工作。

每個 class 當中只能有一個反初始化器。反初始化器不接收任何參數,不需要寫圓括號:

deinit {
    // 執行反初始化
}

反初始化器會在實例被釋放之前自動被調用。你不能自行調用反初始化器。父類的反初始化器可以被子類繼承,並且子類的反初始化器實現結束之後父類的反初始化器會被調用。就算子類沒有反初始化器,父類的反初始化器總是被調用。

由於實例在反初始化器被調用之前都不會被釋放,反初始化器可以訪問實例中的所有屬性並且可以基於這些屬性修改自身行為。


反初始化器應用

這邊我們試著的創建一個反初始化器的應用,參考平常可能使用信用卡或是網路帳戶進行交易的動作:

class Trade {
    var savings:Int

    init(Bank:Int){
        savings = Bank
    }
    func trading(product:String,quantity:Int,price:Int) -> Int {
        let total = price * quantity
        savings -= total + 10
        print("商品為:\(product),數量為:\(quantity),總金額為:\(total)")
        print("交易成功(10$手續費),餘額還剩: $\(savings)")
        return savings
    }
    deinit {
        print("卡片失效,戶頭餘額尚有: $\(savings)")
    }
}

其中,我們在一開始初始化一個帳戶金額,並在其中有一個 trading 的 function , 用來計算每次交易金額以及帳戶餘額,並且印出結果,在最後我們建立反初始化器,如果再我們的 Trade 實例為 nil 時,它會在 Trade 的實例釋放之前被調用。這時,反初始化器會把直接印出我們的帳戶餘額,並印出卡片失效的訊息。

首先我們先初始化我們的帳戶金額,這裡宣告了一個可選變數,是因為可能因為各種因素導致卡片失效(就假設他無法使用La)。

var VisaCard:Trade? = Trade(Bank: 200000)

確認帳戶餘額:
https://ithelp.ithome.com.tw/upload/images/20180110/20107701oQ2KTEDHpQ.png

之後可以利用 trading fuctions 來呼叫交易行為,並印出商品名稱、數量及金額,最後在計算帳戶的餘額,當你在調用我們 Trade 實例中的屬性時,必須加上驚嘆號(!)來調用:

https://ithelp.ithome.com.tw/upload/images/20180110/201077013gQq3yfwlA.png

假如我們之後卡片因為各種原因導致卡片失效(它的值為 nil),這時反初始化就會執行我們預設給他的程序,印出我們的卡片失效以及餘額資訊:

VisaCard = nil

顯示整段程式碼來確認餘額餘額是否正確,呈現如下:
https://ithelp.ithome.com.tw/upload/images/20180110/20107701w94Pq7CVu7.png

當然之後也可以再給這個實例重新賦值,繼續這個實例的運作:

VisaCard = Trade(Bank: 190000)

怎麼有時候內容很短,但想一個範例就想半天,經過實做起來才知道到底簡不簡單難不難,或許有時候沒有想像中複雜。
只怕誤會了程式碼的過程QQ


上一篇
Day-21 Swift 語法(17) - 可失敗初始化器
下一篇
Day-23 Swift 語法(19) - 自動引用計數 (ARC)
系列文
Swift 菜鳥的30天30

尚未有邦友留言

立即登入留言