標籤:
Deinitialization
當類的執行個體對象即將要被釋放時,會立即調用deinitializer,通過deinit關鍵字來定義deinitializer,和initializer一樣,它也只存在於類類型上。
當執行個體對象不再有用時,Swift會自動釋放該對象。Swift通過自動引用計數(ARC)來管理執行個體記憶體。通常情況下,對象被釋放時,你並不需要做特別的清理,但是,如果你操作了你自己的資源,可能需要做一些額外的清理工作。比如,你在某個類中開啟了一個檔案,並往裡寫入了資料,那麼你需要在這個類的執行個體對象釋放前關閉檔案。
一個類最多隻能有一個deinitializer,並且它不接受任何參數,定義方式也是無參數形式:
deinit { // perform the deinitialization}
deinitializer是自動在合適的時刻被調用的,你不能手動調用它。
超類的deinitializer會自動被子類繼承,並且超類的deinitializer會自動在子類的deinitializer實現完成之後被調用。當然,如果子類並沒有提供deinitializer的實現,超類的deinitializer依然會被自動調用。因為執行個體對象是在deinitializer被調用完成之後才會被釋放,因此deinitializer可以訪問執行個體對象的所有屬性,並且基於這些屬性實現一些操作(比如查詢需要被關閉的檔案名稱字)。
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 }}
這裡定義了一個結構體來類比一個簡單的遊戲虛擬銀行,它負責整個遊戲裡的貨幣儲存和借貸,它聲明了一個類型屬性coinsInBank來跟蹤銀行裡面的現金數。這裡vendCoins方法定義了一個變數型參數,這樣它就不用在方法體內部再聲明一個變數然後賦值,而是直接操作這個變數型參數就可以了。
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類比遊戲中的玩家,它聲明一個儲存屬性coinsInPurse來標識這個執行個體對象當前擁有的金幣數。在init和winCoins兩個方法中,雖然接受了一個coins參數,但是並不是直接將其賦值給儲存屬性,而是取決於Bank能夠借貸出來的金幣數。這裡定義了一個deinitializer,在當前執行個體對象被釋放之前將所擁有的金幣歸還給銀行。
var playerOne: Player? = Player(coins: 100)println("A new player has joined the game with \(playerOne!.coinsInPurse) coins")// prints "A new player has joined the game with 100 coins"println("There are now \(Bank.coinsInBank) coins left in the bank")// prints "There are now 9900 coins left in the bank”
這裡定義了一個可選Player類型變數playerOne,之所以定義為可選類型,是因為該玩家可以隨時離開遊戲,即該對象隨時可能被釋放。這裡要訪問它的儲存屬性時,用了隱式展開可選項符號(!),同樣,在調用它的執行個體方法時也要這樣:
playerOne!.winCoins(2_000)println("PlayerOne won 2000 coins & now has \(playerOne!.coinsInPurse) coins")// prints "PlayerOne won 2000 coins & now has 2100 coins"println("The bank now only has \(Bank.coinsInBank) coins left")// prints "The bank now only has 7900 coins left”
當playerOne被釋放時,在此之前會先執行它的deinitializer進行相關的清理工作,即將錢還給銀行:
playerOne = nilprintln("PlayerOne has left the game")// prints "PlayerOne has left the game"println("The bank now has \(Bank.coinsInBank) coins")// prints "The bank now has 10000 coins”
Swift學習筆記十四