★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9739382.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
在取消释放类实例之前,将调用反初始化器。使用deinit
关键字编写反初始化器,类似于使用init
关键字编写初始化器的方式。反初始化器仅在类类型上可用。
反初始化的工作方式
当不再需要实例时,Swift会自动释放其实例,以释放资源。迅速通过处理实例的存储器管理自动引用计数(ARC),如在自动引用计数。通常,在实例被释放后,您无需执行手动清理。但是,当您使用自己的资源时,可能需要自己执行一些额外的清理。例如,如果创建一个自定义类来打开文件并向其中写入一些数据,则可能需要在释放该类实例之前关闭该文件。
每个类定义最多可以有一个反初始化器。反初始化器不接受任何参数,并且写成无括号:
- deinit {
- // perform the deinitialization
- }
在实例解除分配发生之前,会自动调用反初始化器。您不允许自己调用反初始化程序。超类反初始化器由其子类继承,并且超类反初始化器在子类反初始化器实现的末尾自动调用。即使子类没有提供自己的反初始化器,也总是会调用超类反初始化器。
因为实例在调用其实例化程序之后才被释放,所以实例化程序可以访问其实例所具有的所有属性,并可以基于这些属性修改其行为(例如查找需要关闭的文件名) )。
反初始化器的作用
这是一个实际使用的反初始化器的示例。此示例为一个简单的游戏定义了两个新类型,Bank
和Player
。该Bank
班级管理一种人造货币,流通货币永远不能超过10,000个。Bank
游戏中永远只有一个,因此会Bank
被实现为具有类型属性和用于存储和管理其当前状态的方法的类:
- 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
- }
- }
Bank
通过其coinsInBank
属性跟踪当前持有的硬币数量。它还提供了两种方法- distribute(coins:)
和receive(coins:)
-处理硬币的分配和收集。
该distribute(coins:)
方法在分发之前检查银行中是否有足够的硬币。如果没有足够的硬币,则Bank
返回小于请求数量的数字(如果银行中没有剩余硬币,则返回零)。它返回一个整数值以指示所提供的硬币的实际数量。
该receive(coins:)
方法只是将接收到的硬币数量加回到银行的硬币存储中。
本Player
类描述了游戏玩家。每个玩家随时都可以在钱包中存放一定数量的硬币。这由玩家的coinsInPurse
属性表示:
- 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)
- }
- }
每个Player
实例在初始化过程中都会从银行指定数量的硬币开始许可进行初始化,尽管Player
如果没有足够的硬币可用,实例可能会收到少于该数量的硬币。
本Player
类定义了一个win(coins:)
方法,它获取一定数量从银行硬币,并将它们添加到玩家的钱包。该Player
班还实现了deinitializer,这被称为之前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"
Player
创建一个新实例,并要求提供100个硬币(如果有)。该Player
实例存储在Player
名为的可选变量中playerOne
。这里使用一个可选变量,因为玩家可以随时离开游戏。可选功能可让您跟踪游戏中当前是否有玩家。
因为playerOne
是可选的,所以!
当coinsInPurse
访问其属性以打印其默认数量的硬币时,以及在win(coins:)
调用其方法时,都使用感叹号()进行限定:
- 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"
在这里,玩家赢得了2,000个硬币。玩家的钱包现在包含2100个硬币,而银行只剩下7900个硬币。
- 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"
玩家现在已经离开了游戏。这是通过将可选playerOne
变量设置为来表示的nil
,表示“无Player
实例”。发生这种情况时,playerOne
变量对Player
实例的引用已损坏。没有其他属性或变量仍在引用Player
实例,因此将其释放以释放其内存。在此之前,它的反初始化程序会自动被调用,并且其硬币会退还至银行。