//析構(gòu)函數(shù)
//析構(gòu)過(guò)程原理
//Swift 會(huì)自動(dòng)釋放不再需要的實(shí)例以釋放資源吩跋。如自動(dòng)引用計(jì)數(shù)章節(jié)中所講述,Swift 通過(guò) 自動(dòng)引用計(jì)數(shù)(AR C) 處理實(shí)例的內(nèi)存管理。通常當(dāng)你的實(shí)例被釋放時(shí)不需要手動(dòng)地去清理渔工。但是,當(dāng)使用自己的資源時(shí),你可能 需要進(jìn)行一些額外的清理锌钮。例如,如果創(chuàng)建了一個(gè)自定義的類(lèi)來(lái)打開(kāi)一個(gè)文件,并寫(xiě)入一些數(shù)據(jù),你可能需要在 類(lèi)實(shí)例被釋放之前手動(dòng)去關(guān)閉該文件。
// 在類(lèi)的定義中,每個(gè)類(lèi)最多只能有一個(gè)析構(gòu)器,而且析構(gòu)器不帶任何參數(shù),如下所示:
// deinit {
// 執(zhí)行析構(gòu)過(guò)程
// }
// 析構(gòu)器是在實(shí)例釋放發(fā)生前被自動(dòng)調(diào)用引矩。你不能主動(dòng)調(diào)用析構(gòu)器梁丘。子類(lèi)繼承了父類(lèi)的析構(gòu)器,并且在子類(lèi)析構(gòu)器實(shí)現(xiàn)的最后,父類(lèi)的析構(gòu)器會(huì)被自動(dòng)調(diào)用。即使子類(lèi)沒(méi)有提供自己的析構(gòu)器,父類(lèi)的析構(gòu)器也同樣會(huì)被調(diào)用旺韭。因?yàn)橹钡綄?shí)例的析構(gòu)器被調(diào)用后,實(shí)例才會(huì)被釋放,所以析構(gòu)器可以訪問(wèn)實(shí)例的所有屬性,并且可以根據(jù)那些屬性可以修改它的行為(比如查找一個(gè)需要被關(guān)閉的文件)氛谜。
//析構(gòu)函數(shù)實(shí)踐
class Bank {
static var coinsInBank = 10_000
static func disTribute(coins numberOfCoinsRequested: NSInteger) -> NSInteger {
let numberOfCoinsToVend = min(numberOfCoinsRequested, coinsInBank)
coinsInBank -= numberOfCoinsToVend
return numberOfCoinsToVend
}
static func receive(coins: NSInteger) {
coinsInBank += coins
}
}
// Bank 使用 coinsInBank 屬性來(lái)跟蹤它當(dāng)前擁有的硬幣數(shù)量。 Bank 還提供了兩個(gè)方法, distribute(coins:) 和 r eceive(coins:) ,分別用來(lái)處理硬幣的分發(fā)和收 茂翔。
//distribute(coins:) 方法在 Bank 對(duì)象分發(fā)硬幣之前檢查是否有足夠的硬幣混蔼。如果硬幣不足, Bank 對(duì)象會(huì)返回一 個(gè)比請(qǐng)求時(shí)小的數(shù)字(如果 Bank 對(duì)象中沒(méi)有硬幣了就返回 0 )。此方法返回一個(gè)整型值,表示提供的硬幣的實(shí) 際數(shù)量珊燎。
//receive(coins:) 方法只是將 Bank 實(shí)例接收到的硬幣數(shù)目加回硬幣存儲(chǔ)中惭嚣。
// Player 類(lèi)描述了游戲中的一個(gè)玩家。每一個(gè)玩家在任意時(shí)間都有一定數(shù)量的硬幣存儲(chǔ)在他們的錢(qián)包中悔政。這通過(guò)玩 家的 coinsInPurse 屬性來(lái)表示:
class Player {
var coinsInPurse: NSInteger
init(coins: NSInteger) {
coinsInPurse = Bank.disTribute(coins: coins)
}
func win(coins: NSInteger) {
coinsInPurse += Bank.disTribute(coins: coins)
}
deinit {
Bank.receive(coins: coinsInPurse)
}
}
//每個(gè) Player 實(shí)例在初始化的過(guò)程中,都從 Bank 對(duì)象獲取指定數(shù)量的硬幣晚吞。如果沒(méi)有足夠的硬幣可用, Player 實(shí)例可能會(huì)收到比指定數(shù)量少的硬幣.
//Player 類(lèi)定義了一個(gè) win(coins:) 方法,該方法從 Bank 對(duì)象獲取一定數(shù)量的硬幣,并把它們添加到玩家的錢(qián) 包。 Player 類(lèi)還實(shí)現(xiàn)了一個(gè)析構(gòu)器,這個(gè)析構(gòu)器在 Player 實(shí)例釋放前被調(diào)用谋国。在這里,析構(gòu)器的作用只是將玩 家的所有硬幣都返還給 Bank 對(duì)象:
var playerOne: Player? = Player(coins: 100)
print("A new player has joined the game with \(playerOne!.coinsInPurse) coins") // 打印 "A new player has joined the game with 100 coins"
print("There are now \(Bank.coinsInBank) coins left in the bank")
// 打印 "There are now 9900 coins left in the bank"
// 創(chuàng)建一個(gè) Player 實(shí)例的時(shí)候,會(huì)向 Bank 對(duì)象請(qǐng)求 100 個(gè)硬幣,如果有足夠的硬幣可用的話槽地。這個(gè) Player 實(shí)例 存儲(chǔ)在一個(gè)名為 playerOne 的可選類(lèi)型的變量中。這里使用了一個(gè)可選類(lèi)型的變量,因?yàn)橥婕铱梢噪S時(shí)離開(kāi)游 戲,設(shè)置為可選使你可以追蹤玩家當(dāng)前是否在游戲中芦瘾。
// 因?yàn)?playerOne 是可選的,所以訪問(wèn)其 coinsInPurse 屬性來(lái)打印錢(qián)包中的硬幣數(shù)量時(shí),使用感嘆號(hào)( ! )來(lái)解 包:
playerOne!.win(coins: 2_000)
print("PlayerOne won 2000 coins & now has \(playerOne!.coinsInPurse) coins") // 輸出 "PlayerOne won 2000 coins & now has 2100 coins"
print("The bank now only has \(Bank.coinsInBank) coins left")
// 輸出 "The bank now only has 7900 coins left"
// 這里,玩家已經(jīng)贏得了 2,000 枚硬幣,所以玩家的錢(qián)包中現(xiàn)在有 2,100 枚硬幣,而 Bank 對(duì)象只剩余 7,900 枚 硬幣捌蚊。
playerOne = nil
print("PlayerOne has left the game")
// 打印 "PlayerOne has left the game"
print("The bank now has \(Bank.coinsInBank) coins") // 打印 "The bank now has 10000 coins"
//玩家現(xiàn)在已經(jīng)離開(kāi)了游戲。這通過(guò)將可選類(lèi)型的 playerOne 變量設(shè)置為 nil 來(lái)表示,意味著“沒(méi)有 Player 實(shí) 例”近弟。當(dāng)這一切發(fā)生時(shí), playerOne 變量對(duì) Player 實(shí)例的引用被破壞了缅糟。沒(méi)有其它屬性或者變量引用 Player 實(shí) 例,因此該實(shí)例會(huì)被釋放,以便回收內(nèi)存。在這之前,該實(shí)例的析構(gòu)器被自動(dòng)調(diào)用,玩家的硬幣被返還給銀行祷愉。