析构(Deinitialization)
当一个类的实例被回收的时候,析构器(Deinitializer)就会被调用。用关键字
deinit
来定义一个析构器,而且只有类采用析构器,而且一个类只有一个析构器。
析构过程
当类的实例不再被使用的时候就会被自动回收,释放资源。Swift采用自动引用计数(Automatic Reference Counting, ARC)来管理内存,一般情况当类的实例被回收的时候你不需要手动清理。但是,当你和自己的资源打交道,比如你打开了你的文件和读写这些文件,这样你就可能需要执行额外的清理工作了,比如在实例被回收之前关闭文件。
一个类最多只有一个析构器,如下:
deinit {
// perform the deinitialization
}
当一个类的实例被回收的时候,会自动调用这个实例的析构器,不允许程序员手动调用析构器。子类可以继承父类的析构器,而且父类的析构器在子类的析构器的实现之后自动调用。由于析构器在调用之前类的实例还没被回收,所以在析构器里面是可以访问实例的所有属性和调用所有的方法来修改某些状态的,比如获取文件的名字来关闭文件。
析构器示例
以下是一个关于析构器的例子:
class Bank {
static var coinsInBank = 10_000
static func distribute(coins numberOfCoinsRequested: Int) -> Int {
let numberOfCoinsToVend = min(numberOfCoinsRequested, coinsInBank)
coinsInBank -= numberOfCoinsToVend
return numberOfCoinsToVend
}
static func receive(coins: Int) {
coinsInBank += coins
}
}
class Player {
var coinsInPurse: Int
init(coins: Int) {
coinsInPurse = Bank.distribute(coins: coins)
}
func win(coins: Int) {
coinsInPurse += Bank.distribute(coins: coins)
}
deinit {
Bank.receive(coins: coinsInPurse)
}
}
以上定义两个类Bank
和Player
,整个游戏期间,只有一个Bank
,而且最多有10000块金币。但是可以有多个Player
,每生成一个Player
都会使Bank
的金币减少一些,但是一个Player
挂掉之后,这些金币将会被回收,所以在析构器中释放了所有的金币。
var playerOne: Player? = Player(coins: 100)
print("A new player has joined the game with \(playerOne!.coinsInPurse) coins")
// Prints "A new player has joined the game with 100 coins"
print("There are now \(Bank.coinsInBank) coins left in the bank")
// Prints "There are now 9900 coins left in the bank"
playerOne!.win(coins: 2_000)
print("PlayerOne won 2000 coins & now has \(playerOne!.coinsInPurse) coins")
// Prints "PlayerOne won 2000 coins & now has 2100 coins"
print("The bank now only has \(Bank.coinsInBank) coins left")
// Prints "The bank now only has 7900 coins left”
playerOne = nil
print("PlayerOne has left the game")
// Prints "PlayerOne has left the game"
print("The bank now has \(Bank.coinsInBank) coins")
// Prints "The bank now has 10000 coins"