为有牺牲多壮志,敢教日月换新天。

Swift5.4 语言指南(十七) 反初始化

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9739382.html 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

在取消分配类实例之前,将立即调用一个反初始化器。您使用deinit关键字编写反初始化器,类似于使用init关键字编写初始化器的方式反初始化器仅适用于类类型。

反初始化的工作方式

当不再需要实例时,Swift会自动释放其实例,以释放资源。迅速通过处理实例的存储器管理自动引用计数ARC),如在自动引用计数通常,在实例被释放后,您无需执行手动清理。但是,当您使用自己的资源时,可能需要自己执行一些额外的清理。例如,如果创建一个自定义类来打开文件并向其中写入一些数据,则可能需要在释放该类实例之前关闭该文件。

每个类定义最多可以有一个反初始化器。反初始化器不接受任何参数,并且在编写时不带括号:

  1. deinit {
  2. // perform the deinitialization
  3. }

在实例解除分配发生之前,会自动调用反初始化器。您不允许自己调用反初始化器。超类反初始化器由其子类继承,并且超类反初始化器在子类反初始化器实现的末尾自动调用。即使子类没有提供自己的反初始化器,也总是会调用超类反初始化器。

由于实例在调用其实例化程序之后才被释放,因此实例化程序可以访问其实例的所有属性,并可以基于这些属性修改其行为(例如查找需要关闭的文件名) )。

反初始化器的作用

这是一个实际使用的反初始化器的示例。本示例为一个简单的游戏定义了两个新类型,BankPlayerBank课程管理一种人造货币,流通中的硬币永远不能超过10,000个。Bank游戏中可能永远只有一个,因此Bank该类被实现为具有类型属性和用于存储和管理其当前状态的方法的类:

  1. class Bank {
  2. static var coinsInBank = 10_000
  3. static func distribute(coins numberOfCoinsRequested: Int) -> Int {
  4. let numberOfCoinsToVend = min(numberOfCoinsRequested, coinsInBank)
  5. coinsInBank -= numberOfCoinsToVend
  6. return numberOfCoinsToVend
  7. }
  8. static func receive(coins: Int) {
  9. coinsInBank += coins
  10. }
  11. }

Bank通过其coinsInBank属性跟踪当前持有的硬币数量它还提供了两种方法-distribute(coins:)receive(coins:)-处理硬币的分配和收集。

distribute(coins:)方法在分发之前检查银行中是否有足够的硬币。如果没有足够的硬币,则Bank返回小于请求数量的数字(如果银行中没有剩余硬币,则返回零)。它返回一个整数值以指示所提供的硬币的实际数量。

receive(coins:)方法只是将接收到的硬币数量加回到银行的硬币存储中。

Player类描述了游戏玩家。每个玩家随时都有一定数量的硬币存储在他们的钱包中。这由玩家的coinsInPurse属性表示:

  1. class Player {
  2. var coinsInPurse: Int
  3. init(coins: Int) {
  4. coinsInPurse = Bank.distribute(coins: coins)
  5. }
  6. func win(coins: Int) {
  7. coinsInPurse += Bank.distribute(coins: coins)
  8. }
  9. deinit {
  10. Bank.receive(coins: coinsInPurse)
  11. }
  12. }

Player在初始化过程中,使用Player实例从银行指定数量的硬币开始配额来初始化每个实例,尽管如果没有足够的硬币可用,实例可能会收到少于该数量实例。

Player类定义了一个win(coins:)方法,它获取一定数量从银行硬币,并将它们添加到玩家的钱包。Player班还实现了deinitializer,这被称为之前Player实例被释放。在这里,解初始化器只是将玩家的所有硬币返回银行:

  1. var playerOne: Player? = Player(coins: 100)
  2. print("A new player has joined the game with \(playerOne!.coinsInPurse) coins")
  3. // Prints "A new player has joined the game with 100 coins"
  4. print("There are now \(Bank.coinsInBank) coins left in the bank")
  5. // Prints "There are now 9900 coins left in the bank"

Player创建一个新实例,并请求提供100个硬币(如果有)。Player实例存储在Player名为的可选变量中playerOne这里使用一个可选变量,因为玩家可以随时离开游戏。可选功能可让您跟踪游戏中当前是否有玩家。

因为playerOne是可选的,所以!coinsInPurse访问属性以打印其默认数量的硬币时,以及每次win(coins:)调用方法,它都带有感叹号(限定

  1. playerOne!.win(coins: 2_000)
  2. print("PlayerOne won 2000 coins & now has \(playerOne!.coinsInPurse) coins")
  3. // Prints "PlayerOne won 2000 coins & now has 2100 coins"
  4. print("The bank now only has \(Bank.coinsInBank) coins left")
  5. // Prints "The bank now only has 7900 coins left"

在这里,玩家赢得了2,000个硬币。玩家的钱包现在包含2100个硬币,而银行只剩下7900个硬币。

  1. playerOne = nil
  2. print("PlayerOne has left the game")
  3. // Prints "PlayerOne has left the game"
  4. print("The bank now has \(Bank.coinsInBank) coins")
  5. // Prints "The bank now has 10000 coins"

玩家现在已经离开了游戏。这是通过将可选playerOne变量设置为来表示的nil,表示“无Player实例”。发生这种情况时,playerOne变量对Player实例的引用已损坏。没有其他属性或变量仍在引用该Player实例,因此已对其进行释放以释放其内存。在此之前,它的反初始化程序会自动被调用,并且其硬币会退还给银行。

 

 
posted @ 2018-10-03 11:07  为敢技术  阅读(213)  评论(0编辑  收藏  举报