Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1313: languageguide deinitializationmd⭐️⭐️⭐️ #1361

Merged
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 32 additions & 100 deletions swift-6-beta.docc/LanguageGuide/Deinitialization.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,12 @@
<!--
要翻译的文件:https://github.com/SwiftGGTeam/the-swift-programming-language-in-chinese/blob/swift-6-beta-translation/swift-6-beta.docc/LanguageGuide/Deinitialization.md
Swift 文档源文件地址:https://docs.swift.org/swift-book/documentation/the-swift-programming-language/deinitialization
翻译估计用时:⭐️⭐️⭐️
-->

# Deinitialization

Release resources that require custom cleanup.
loshoc marked this conversation as resolved.
Show resolved Hide resolved
# 析构过程

A *deinitializer* is called immediately before a class instance is deallocated.
You write deinitializers with the `deinit` keyword,
similar to how initializers are written with the `init` keyword.
Deinitializers are only available on class types.
析构器仅适用于类类型,*析构器* 会在类实例被释放之前立即调用。使用 `deinit` 关键字来编写析构器,类似于使用 `init` 关键字编写构造器。
loshoc marked this conversation as resolved.
Show resolved Hide resolved

## How Deinitialization Works
## 析构过程原理

Swift automatically deallocates your instances when they're no longer needed,
to free up resources.
Swift handles the memory management of instances through
*automatic reference counting* (*ARC*),
as described in <doc:AutomaticReferenceCounting>.
Typically you don't need to perform manual cleanup when your instances are deallocated.
However, when you are working with your own resources,
you might need to perform some additional cleanup yourself.
For example, if you create a custom class to open a file and write some data to it,
you might need to close the file before the class instance is deallocated.
Swift 会在实例不再需要时自动释放它们,以释放资源。Swift 通过*自动引用计数*(*ARC*)来管理实例的内存,如 <doc:AutomaticReferenceCounting> 中所述。通常,在实例被释放时不需要执行手动清理。然而,当你处理自己的资源时,可能需要进行一些额外的清理。例如,如果创建一个自定义类来打开文件并向其中写入数据,可能需要在类实例被释放之前关闭文件。
loshoc marked this conversation as resolved.
Show resolved Hide resolved

Class definitions can have at most one deinitializer per class.
The deinitializer doesn't take any parameters
and is written without parentheses:
类定义中每个类最多只能有一个析构器。析构器不接受任何参数,并且是没有括号的:

```swift
deinit {
loshoc marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -48,28 +26,13 @@ deinit {
```
-->

Deinitializers are called automatically, just before instance deallocation takes place.
You aren't allowed to call a deinitializer yourself.
Superclass deinitializers are inherited by their subclasses,
and the superclass deinitializer is called automatically at the end of
a subclass deinitializer implementation.
Superclass deinitializers are always called,
even if a subclass doesn't provide its own deinitializer.

Because an instance isn't deallocated until after its deinitializer is called,
a deinitializer can access all properties of the instance it's called on
and can modify its behavior based on those properties
(such as looking up the name of a file that needs to be closed).

## Deinitializers in Action

Here's an example of a deinitializer in action.
This example defines two new types, `Bank` and `Player`, for a simple game.
The `Bank` class manages a made-up currency,
which can never have more than 10,000 coins in circulation.
There can only ever be one `Bank` in the game,
and so the `Bank` is implemented as a class with type properties and methods
to store and manage its current state:
析构器会在实例释放之前自动调用。不能自行调用析构器。父类的析构器会被子类继承,并且在子类析构器实现的末尾自动调用父类的析构器。父类的析构器总是会被调用,即使子类没有提供自己的析构器。
loshoc marked this conversation as resolved.
Show resolved Hide resolved

由于实例在析构器调用完成后才会被释放,因此析构器可以访问其调用的实例的所有属性,并可以根据这些属性修改其行为(例如查找需要关闭的文件的名称)。
loshoc marked this conversation as resolved.
Show resolved Hide resolved

## 析构器实践

下面是一个析构器实际应用的例子。这个例子定义了两个新类型,`Bank` 和 `Player`,用于一个简单的游戏。`Bank` 类管理一种虚构的货币,这种货币的流通量永远不会超过 10,000 个金币。游戏中只能有一个 `Bank`,因此 `Bank` 实现为一个类,使用类型属性和方法来存储和管理其当前状态:
loshoc marked this conversation as resolved.
Show resolved Hide resolved
loshoc marked this conversation as resolved.
Show resolved Hide resolved
loshoc marked this conversation as resolved.
Show resolved Hide resolved

```swift
class Bank {
Expand Down Expand Up @@ -103,21 +66,13 @@ class Bank {
```
-->

`Bank` keeps track of the current number of coins it holds with its `coinsInBank` property.
It also offers two methods --- `distribute(coins:)` and `receive(coins:)` ---
to handle the distribution and collection of coins.
`Bank` 通过其 `coinsInBank` 属性跟踪当前持有的金币数量。它还提供了两个方法——`distribute(coins:)` 和 `receive(coins:)`——来处理金币的分发和回收。
loshoc marked this conversation as resolved.
Show resolved Hide resolved

The `distribute(coins:)` method checks that there are enough coins in the bank before distributing them.
If there aren't enough coins,
`Bank` returns a smaller number than the number that was requested
(and returns zero if no coins are left in the bank).
It returns an integer value to indicate the actual number of coins that were provided.
`distribute(coins:)` 方法在分发金币之前检查银行中是否有足够的金币。如果金币不足,`Bank` 会返回一个比请求的数量更小的数字(如果银行中没有金币,则返回零)。该方法返回一个整数值,表示实际提供的金币数量。
loshoc marked this conversation as resolved.
Show resolved Hide resolved

The `receive(coins:)` method simply adds the received number of coins back into the bank's coin store.
`receive(coins:)` 方法只是将接收到的金币数量重新添加到银行的金币库中。

The `Player` class describes a player in the game.
Each player has a certain number of coins stored in their purse at any time.
This is represented by the player's `coinsInPurse` property:
`Player` 类描述了游戏中的一个玩家。每个玩家在任何时候都有一定数量的金币存储在他们的钱包中。这由玩家的 `coinsInPurse` 属性表示:
loshoc marked this conversation as resolved.
Show resolved Hide resolved

```swift
class Player {
Expand Down Expand Up @@ -153,24 +108,16 @@ class Player {
```
-->

Each `Player` instance is initialized with a starting allowance of
a specified number of coins from the bank during initialization,
although a `Player` instance may receive fewer than that number
if not enough coins are available.
每个 `Player` 实例在初始化时都会从银行获得指定数量的初始金币津贴,尽管如果金币不足,`Player` 实例可能会收到少于该数量的金币。
loshoc marked this conversation as resolved.
Show resolved Hide resolved
loshoc marked this conversation as resolved.
Show resolved Hide resolved

The `Player` class defines a `win(coins:)` method,
which retrieves a certain number of coins from the bank
and adds them to the player's purse.
The `Player` class also implements a deinitializer,
which is called just before a `Player` instance is deallocated.
Here, the deinitializer simply returns all of the player's coins to the bank:
`Player` 类定义了一个 `win(coins:)` 方法,该方法从银行获取一定数量的金币并将其添加到玩家的钱包中。`Player` 类还实现了一个析构器,该析构器在 `Player` 实例被释放之前调用。在这里,析构器只是将玩家的所有金币返还给银行:

```swift
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"
// 打印 "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"
// 打印 "There are now 9900 coins left in the bank"
```

<!--
Expand All @@ -185,21 +132,16 @@ print("There are now \(Bank.coinsInBank) coins left in the bank")
```
-->

A new `Player` instance is created, with a request for 100 coins if they're available.
This `Player` instance is stored in an optional `Player` variable called `playerOne`.
An optional variable is used here, because players can leave the game at any point.
The optional lets you track whether there's currently a player in the game.
创建了一个新的 `Player` 实例的时候,会向 `Bank` 请求获取 100 个金币(如果有的话)。这个 `Player` 实例被存储在一个名为 `playerOne` 的可选型 `Player` 变量中。这里使用可选变量是因为玩家可以在任何时候退出游戏。通过可选型可以跟踪当前是否有玩家在游戏中。
loshoc marked this conversation as resolved.
Show resolved Hide resolved
loshoc marked this conversation as resolved.
Show resolved Hide resolved
loshoc marked this conversation as resolved.
Show resolved Hide resolved

Because `playerOne` is an optional, it's qualified with an exclamation point (`!`)
when its `coinsInPurse` property is accessed to print its default number of coins,
and whenever its `win(coins:)` method is called:
由于 `playerOne` 是一个可选型,因此在访问其 `coinsInPurse` 属性以打印默认金币数量时,以及每次调用其 `win(coins:)` 方法时,都需要使用感叹号(`!`)来强制解包:
loshoc marked this conversation as resolved.
Show resolved Hide resolved

```swift
playerOne!.win(coins: 2_000)
print("PlayerOne won 2000 coins & now has \(playerOne!.coinsInPurse) coins")
// Prints "PlayerOne won 2000 coins & now has 2100 coins"
// 打印 "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"
// 打印 "The bank now only has 7900 coins left"
```

<!--
Expand All @@ -214,16 +156,14 @@ print("The bank now only has \(Bank.coinsInBank) coins left")
```
-->

Here, the player has won 2,000 coins.
The player's purse now contains 2,100 coins,
and the bank has only 7,900 coins left.
在这里,玩家赢得了 2,000 个金币。玩家的钱包现在包含 2,100 个金币,而银行只剩下 7,900 个金币。
loshoc marked this conversation as resolved.
Show resolved Hide resolved

```swift
playerOne = nil
print("PlayerOne has left the game")
// Prints "PlayerOne has left the game"
// 打印 "PlayerOne has left the game"
print("The bank now has \(Bank.coinsInBank) coins")
// Prints "The bank now has 10000 coins"
// 打印 "The bank now has 10000 coins"
```

<!--
Expand All @@ -238,21 +178,13 @@ print("The bank now has \(Bank.coinsInBank) coins")
```
-->

The player has now left the game.
This is indicated by setting the optional `playerOne` variable to `nil`,
meaning “no `Player` instance.”
At the point that this happens,
the `playerOne` variable's reference to the `Player` instance is broken.
No other properties or variables are still referring to the `Player` instance,
and so it's deallocated in order to free up its memory.
Just before this happens, its deinitializer is called automatically,
and its coins are returned to the bank.

> Beta Software:
玩家现在已经退出游戏。这通过将可选型变量 `playerOne` 设置为 `nil` 来表示,意味着“没有 `Player` 实例。”在这一刻,`playerOne` 变量对 `Player` 实例的引用被断开。没有其他属性或变量仍然引用该 `Player` 实例,因此它会被释放以释放其内存。在这发生之前,它的析构器会自动调用,并将其金币返还给银行。
loshoc marked this conversation as resolved.
Show resolved Hide resolved
loshoc marked this conversation as resolved.
Show resolved Hide resolved
loshoc marked this conversation as resolved.
Show resolved Hide resolved
loshoc marked this conversation as resolved.
Show resolved Hide resolved
loshoc marked this conversation as resolved.
Show resolved Hide resolved

> 测试版软件:
>
> This documentation contains preliminary information about an API or technology in development. This information is subject to change, and software implemented according to this documentation should be tested with final operating system software.
> 本文档包含关于开发中 API 或技术的初步信息。此信息可能会发生变化,并且根据本文档实施的软件应与最终的操作系统软件一起进行测试。
loshoc marked this conversation as resolved.
Show resolved Hide resolved
>
> Learn more about using [Apple's beta software](https://developer.apple.com/support/beta-software/).
> 了解更多关于[Apple 测试版软件](https://developer.apple.com/support/beta-software/)的使用。

<!--
This source file is part of the Swift.org open source project
Expand Down