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