初期化解除
日本語を消す 英語を消す下記URLから引用し、日本語訳をつけてみました。
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/deinitialization
Release resources that require custom cleanup.
カスタム クリーンアップが必要なリソースを解放します。
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.
ディイニシャライザは、クラス インスタンスの割り当てが解除される直前に呼び出されます。 init
キーワードを使用してイニシャライザを記述する方法と同様に、deinit
キーワードを使用してディイニシャライザを記述します。 ディイニシャライザはクラス型でのみ使用できます。
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 Automatic Reference Counting. 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) を通じてインスタンスのメモリ管理を処理します。 通常、インスタンスの割り当てが解除されたときに手動でクリーンアップを実行する必要はありません。 ただし、独自のリソースを使用している場合は、追加のクリーンアップを自分で実行する必要がある場合があります。 たとえば、ファイルを開いてデータを書き込むカスタム クラスを作成する場合、クラス インスタンスの割り当てが解除される前にファイルを閉じる必要がある場合があります。
Class definitions can have at most one deinitializer per class. The deinitializer doesn’t take any parameters and is written without parentheses:
クラス定義には、クラスごとに最大 1 つのデイニシャライザを含めることができます。 ディイニシャライザはパラメータをとらず、かっこなしで記述されます。
deinit {
// perform the deinitialization
}
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:
以下は、ディイニシャライザの動作の例です。 この例では、単純なゲーム用に 2 つの新しいタイプ、Bank
と Player
を定義します。 Bank
クラスは、流通するコインが 10,000 枚を超えることのない、作成された通貨を管理します。 ゲーム内に存在できるBank
は 1 つだけであるため、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
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
プロパティを使用して、現在の保有コイン数を追跡します。 また、コインの配布と収集を処理するための 2 つのメソッド、distribute(coins:)
と receive(coins:)
も提供します。
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
はリクエストされた数よりも小さい数を返します(銀行にコインが残っていない場合は 0 を返します)。 実際に提供されたコインの数を示す整数値を返します。
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
プロパティによって表されます。
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)
}
}
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
インスタンスはその数よりも少ないコインを受け取ることがあります。
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
インスタンスの割り当てが解除される直前に呼び出されるディイニシャライザも実装します。 ここで、ディイニシャライザは単純にプレーヤーのコインをすべて銀行に返します。
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"
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
インスタンスが作成され、利用可能な場合は 100 コインがリクエストされます。 この Player
インスタンスは、playerOne
というオプションの Player
変数に保存されます。 プレーヤーはいつでもゲームから離れることができるため、ここではオプションの変数が使用されます。 オプションを使用すると、現在ゲームにプレイヤーがいるかどうかを追跡できます。
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:)
メソッドが呼び出されるたびに、感嘆符 (!
) で修飾されます。
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"
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 枚のコインしか残っていません。
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"
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.
プレイヤーはゲームから退出しました。 これは、オプションの playerOne
変数を nil
に設定することで示されます。これは、「Player
インスタンスがない」ことを意味します。 これが発生した時点で、playerOne
変数の Player
インスタンスへの参照は壊れています。 他のプロパティや変数はまだ Player
インスタンスを参照していないため、メモリを解放するために割り当てが解除されます。 これが起こる直前に、そのディイニシャライザが自動的に呼び出され、そのコインが銀行に返されます。