Deinitialization¶ デイニシャライズ¶
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. スウィフトは自動的に、それらがもはや必要とされない場合はあなたのインスタンスを割り当て解除して、資源を自由に使えるようにします。スウィフトは、自動参照カウントで記述されるように、インスタンスのメモリ管理を自動参照カウント(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個以上のコインを決して持つことができません。1つの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
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
は要請された数より少ない数を返します(そしてコインが胴元に残っていないならばゼロを返します)。それは、提供されたコインの実際の数を示す整数値を返します。
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"(「新しいプレーヤーが、100のコインを持ってゲームに参加しました」を出力します)
- print("There are now \(Bank.coinsInBank) coins left in the bank")
- // Prints "There are now 9900 coins left in the bank"(「現在9900個のコインが胴元に残されます」を出力します)
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"(「PlayerOneは2000のコインを獲得&現在2100のコインを持ちます」を出力します)
- print("The bank now only has \(Bank.coinsInBank) coins left")
- // Prints "The bank now only has 7900 coins left"(「胴元には現在7900個のコインだけが残っています」を出力します)
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"(「PlayerOneは、ゲームを離れました」を出力します)
- print("The bank now has \(Bank.coinsInBank) coins")
- // Prints "The bank now has 10000 coins"(「胴元には現在10000コインがあります」を出力します)
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
変数に、「Player
インスタンスがない」ことを意味する、nil
を設定することによって示されます。これが起こる時点で、playerOne
変数のもつPlayer
インスタンスへの参照は壊れています。他のいかなるプロパティまたは変数も、もはやPlayer
インスタンスに言及していません、なのでそれは、それのもつメモリを開放するために順次割り当て解除されます。これが起こる直前に、そのデイニシャライザは自動的に呼ばれます、そしてそのコインは胴元に返されます。