Swift学习24:反初始化器deinit

张建 lol

前言

  • Swift 的析构过程,在类的实例被释放前,析构函数被立即调用,析构函数只使用于类的类型。

  • 析构器deinit 关键字来表示,也叫 反初始化器,不带任何参数

  • 构造器init 关键字来表示,也叫 初始化器,可以带参数

deinit 析构过程

  • Swift 是通过 自动引用计数(ARC) 处理实例的内存管理,自动释放不再需要的实例以释放资源

  • 析构器在实例释放发生前自动调用,你不能主动调用析构器

  • 通常当实例被释放时不需要手动去清理。但是,当使用自己的资源时,可能需要进行一些额外的清理

例如:自定义的类打开一个文件并写入一些数据,可能需要在类实例被释放之前关闭该文件

deinit 语法

在类的定义中,每个类最多只能有一个析构函数,析构函数不带有任何参数,在语法上不带圆括号

1
2
3
deinit {
// 执行析构过程
}

举例

描述了一个简单的游戏,这里定义了两种新类型,分别是 BankPlayer

Bank 类管理一种虚拟硬币,确保流通的硬币数量永远不可能超过 10,000。在游戏中有且只能有一个 Bank 存在,因此 Bank 用类来实现,并使用类型属性和类型方法来存储和管理其当前状态。(比单例的设计要好,单例的内存不会被释放)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Bank {
// 类型属性:硬币数量
static var coinsInBank = 10_000;

// 类型方法:分发硬币之前检查是否有足够的硬币
static func distribute(coins numberOfCoinsRequest: Int) -> Int {
// 可分发的硬币数量
let numberOfCoinToVend = min(numberOfCoinsRequest, coinsInBank);
// 银行剩余硬币数量
coinsInBank -= numberOfCoinToVend;
// 返回银行可分发的硬币数量
return numberOfCoinToVend;
}

// 类型属性:将 Bank 实例接收到的硬币数目加回硬币存储中
static func receive(coins: Int) {
coinsInBank += coins;
}
}

Player 类描述了游戏中的一个玩家。每一个玩家在任意时间都有一定数量的硬币存储在他们的钱包中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Player {
// 玩家的钱包
var coinsInPurse: Int

// 初始化从 Bank 对象获取指定数量的硬币
init(coins: Int) {
coinsInPurse = Bank.distribute(coins: coins)
}

// 从 Bank 对象 赢取 一定数量的硬币,把它们添加到玩家的钱包
func win(coins: Int) {
coinsInPurse += Bank.distribute(coins: coins)
}

// 析构器被自动调用
deinit {
// 查询 Player 的硬币
print("Bank回收之前,Player的硬币数量:\(coinsInPurse)")
// 查询 Bank 的硬币
print("Bank回收之前,Bank的硬币数量:\(Bank.coinsInBank)")

// 玩家钱包中的硬币返回给银行
Bank.receive(coins: coinsInPurse)
coinsInPurse = 0;

// 查询 Player 的硬币
print("Bank回收之后,Player的硬币数量:\(coinsInPurse)")
// 查询 Bank 的硬币
print("Bank回收之后,Bank的硬币数量:\(Bank.coinsInBank)")
}
}

假设玩家从银行初次获取 3000 硬币,后又赢取 1000 硬币

1
2
3
4
5
6
7
8
9
10
11
12
class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

// 实例化 Player 从 Bank 获取 3000 硬币
let player = Player(coins: 3000)
// Player 从 Bank 赢取 100 硬币
player.win(coins: 1000)

}
}

当玩家的硬币由于某些原因被回收后,查看打印结果

1
2
3
4
Bank回收之前,Player的硬币数量:4000
Bank回收之前,Bank的硬币数量:6000
Bank回收之后,Player的硬币数量:0
Bank回收之后,Bank的硬币数量:10000

总结

  • 析构过程调用的方法是 deinit {}。类似 OCdealloc

  • deinit 通过 ARC 自动处理,不需要手动操作,也会自动调用父类的 deinit

  • deinit 里处理对象将要被释放时的一些操作

  • Post title:Swift学习24:反初始化器deinit
  • Post author:张建
  • Create time:2023-03-26 18:42:37
  • Post link:https://redefine.ohevan.com/2023/03/26/Swift/Swift学习24:反初始化器deinit/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
On this page
Swift学习24:反初始化器deinit