import Foundation
//***********************************************************************************************
//1.Deinitialization(反初始化)
//_______________________________________________________________________________________________
//介绍
//在一个类的实例被释放之前,反初始化函数被立即调用。用关键字 deinit 来标示反初始化函数,类似于初始化函数用 init 来标示。反初始化函数只适用于类类型
//***********************************************************************************************
//2.How Deinitialization Works(反初始化原理)
//_______________________________________________________________________________________________
//原理介绍
//Swift 会自动释放不再需要的实例以释放资源。如自动引用计数那一章描述,Swift 通过自动 引用计数(ARC)处理实例的内存管理,通常当你的实例被释放时不需要手动的去清理。但是,当使用自己的资源时,你可能需要进行一些额外的清理。例如,如果创建了一个自定 义 的类来打开一个文件,并写入一些数据,你可能需要在类实例被释放之前关闭该文件
//在类的定义中,每个类最多只能有一个反初始化函数
//反初始化函数是在实例释放发生前一步被自动调用。不允许主动调用自己的反初始化函数。 子类继承了父类的反初始化函数,并且在子类反初始化函数实现的最后,父类的反初始化函 数被自动调用。即使子类没有提供自己的反初始化函数,父类的反初始化函数也总是被调用
//因为直到实例的反初始化函数被调用时,实例才会被释放,所以反初始化函数可以访问所有 请求实例的属性,并且根据那些属性可以修改它的行为
//_______________________________________________________________________________________________
//实例代码演示反初始化函数的操作
struct Bank{ //Bank 结构体管理一个虚拟货币的流通,在这个流通中 Bank 永远不可能拥 有超过 10,000 的硬币
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){ //通过方法处理硬币的收集,将 bank 的硬币存储和接收到的硬币数目相加,再保存回 bank
coinsInBank += coins
}
}
class Player{
var coinsInPurse: Int
init(coins: Int){
coinsInPurse = Bank.vendCoins(coins)
}
func winCoins(coins: Int){ //该方法从 bank 获取一定数量的硬币,并把它们添加到 player 的钱包
coinsInPurse += Bank.vendCoins(coins)
}
deinit{ //反初始化函数,这个反初始化函数在 Player 实例 释放前一步被调用。这里反初始化函数只是将 player 的所有硬币都返回给 bank
Bank.receiveCoins(coinsInPurse)
}
}
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("PlayOne won 2000 coins & now has \(playerOne!.coinsInPurse) coins")
println ("The bank now only has \(Bank.coinsInBank) coins left ")
playerOne = nil //当用户离开的时候,这个实例被释放,调用 deinit 方法
println("playerOne has left the game")
println ("The bank now has \(Bank.coinsInBank) coins ")