天天看點

析構—Swift學習筆記(十八)

注:本文為自己學習The Swift Programming Language的筆記,其中的例子為引用原書和其他博文或自己原創的。每個例子都會批注一些實踐過程中的經驗或思考總結。

1.基礎

析構過程[deinitialization]由析構函數[deinitializer]完成,類的執行個體在被回收資源之前析構函數被調用,隻有類才有析構函數。定義析構函數使用關鍵字deinit,格式和構造函數相同。

2.析構過程的完成

Swift自動回收不再使用的執行個體以釋放資源,它通過自動引用計數[automatic reference counting,AFC]實作執行個體的記憶體管理。程式員不需要人工的實作執行個體回收,但是可以在回收之前完成一些有必要的工作:比如一個打開檔案并通路檔案的類在回收之前一定要關閉檔案才行,這項工作可以交給析構函數來完成,它在類的執行個體在被回收資源之前被調用。

一個類最多能有一個析構函數,析構函數沒有任何穿入參數也沒有傳回值:

deinit {
    // perform the deinitialization
}
           

析構函數是自動調用的,不能顯式的調用它。子類繼承超類的析構函數,子類的析構函數的實作完成之前自動調用超類析構函數,即使子類沒有自己的析構函數超類的析構函數仍然在子類執行個體被回收時自動調用。

因為析構函數是在回收之前被調用的,它可以通路修改所有的屬性并根據這些屬性值做出相應工作。

3.析構過程的實作

通過一個例子來熟悉析構函數的使用,例子中包括了兩個類型Bank和Player。Bank結構體管理一種流通量不超過10000的虛拟貨币,因為隻有一個Bank是以結構體和靜态屬性和方法實作:

struct Bank {
    static var coinsInBank = 10_000
    static func vendCoins(var numberOfCoinsToVend: Int) -> Int {
        numberOfCoinsToVend = min(numberOfCoinsToVend, coinsInBank)
        coinsInBank -= numberOfCoinsToVend
        return numberOfCoinsToVend
    }
    static func receiveCoins(coins: Int) {
        coinsInBank += coins
    }
}
           

Bank記錄目前銀行剩餘貨币,并有一個配置設定貨币方法和收回貨币方法,它們都是靜态的。

Player類描述了遊戲中的玩家,每個玩家錢包裡有一些初始的貨币,它可以從銀行中赢取貨币。Player類有一個析構函數,它實作了在Player執行個體被回收時将其持有貨币收回銀行,保證總的貨币數保持10000:

class Player {
    var coinsInPurse: Int
    init(coins: Int) {
        coinsInPurse = Bank.vendCoins(coins)
    }
    func winCoins(coins: Int) {
        coinsInPurse += Bank.vendCoins(coins)
    }
    deinit {
        Bank.receiveCoins(coinsInPurse)
    }
}
           

通過跟蹤player執行個體和Bank結構體的總貨币數來了解析構過程:

var playerOne: Player? = Player(coins: 100)
println("A new player has joined the game with \(playerOne!.coinsInPurse) coins")
println("There are now \(Bank.coinsInBank) coins left in the bank")

playerOne!.winCoins(2_000)
println("PlayerOne won 2000 coins & now has \(playerOne!.coinsInPurse) coins")
println("The bank now only has \(Bank.coinsInBank) coins left")

playerOne = nil
println("PlayerOne has left the game")
println("The bank now has \(Bank.coinsInBank) coins")

/*
prints
    A new player has joined the game with 100 coins
    There are now 9900 coins left in the bank
    PlayerOne won 2000 coins & now has 2100 coins
    The bank now only has 7900 coins left
    PlayerOne has left the game
    The bank now has 10000 coins
*/
           

playerOne指派nil時Swift自動回收之前的執行個體,調用Player類的析構函數把玩家剩餘貨币返還給銀行。