Swift:16 析構
在類實例釋放之前,析構器(deinitializer)會被立即調用。和使用init關鍵詞來聲明構造器一樣,使用deinit關鍵詞來聲明析構器。析構器只能在類類型中聲明。
析構原理
Swift會自動釋放不再需要使用的實例,從而讓資源得到回收。Swift通過自動引用計數(ARC)來管理實例內存。通常在釋放實例資源時不需要手動清理,但使用自定義的資源時,就可能需要額外的清理操作。比如你創建了一個自定義的類來打開并且寫入一個文件,你可能需要在類實例被釋放前關閉這個文件。
在類的定義中,每個類最多只能有一個析構器。析構器不接收任何形參,并且不帶圓括號:
deinit{
//析構代碼
}
析構器在實例釋放發生前被自動調用,不允許主動調用析構器。子類繼承了超類的析構器,在定義子類析構器的最后自動調用超類的析構器。即使子類沒有提供自己的析構器,超類的析構器也還是會被調用。
示例
下面示例聲明了一個Store倉庫類來存儲所有的金幣,Store倉庫的金幣總數是固定的,通過Store的distribute(golds required:Int)方法來發放金幣。Player玩家初始化會有一定的金幣數,通過win(golds:Int)方法來獲取更多的金幣。通過聲明Player的可選類型,這樣就可以手動的釋放player這個類實例,一旦player被釋放,就會自動執行deinit,把player中的金幣歸還給Store倉庫。
class Store {
static var totalGolds = 10_000
static func distribute(golds required: Int)->Int{
let shoulded = min(required,totalGolds)
totalGolds -= shoulded
return shoulded
}
static func receive(coins:Int){
totalGolds += coins
}
}
class Player{
var golds:Int
init(golds:Int) {
self.golds = Store.distribute(golds: golds)
}
func win(golds:Int) {
self.golds += Store.distribute(golds: golds)
}
deinit {
Store.receive(coins: golds)
}
}
var player:Player? = Player(golds: 100)
print("玩家初始化金幣數為:\(player!.golds)")
print("倉庫中還剩余金幣數:\(Store.totalGolds)")
player!.win(golds: 2000)
print("玩家現在金幣數為:\(player!.golds)")
print("倉庫中還剩余金幣數:\(Store.totalGolds)")
player = nil
print("倉庫中現在金幣數:\(Store.totalGolds)")
代碼執行結果截圖如下。
示例代碼
https://github.com/99ios/23.17