* 내가 읽으려고 내 맘대로 번역한 글.
* 원문 : https://docs.swift.org/swift-book/LanguageGuide/Deinitialization.html

* deinitialization : '해제'  라고 내맘대로 이름붙임.

* deinitializer : '해제자' 라고 내맘대로 이름붙임.

 

 

 

 

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 are 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 does not take any parameters and is written without parentheses:

클래스당 최대 하나의 해제자를 가질수 있다.

해제자는 매개변수를 하나도 받지 않고 괄호도 없이 쓴다.

deinit {
	// perform the deinitialization
}

 

Deinitializers are called automatically, just before instance deallocation takes place. You are not 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 does not provide its own deinitializer.

해제자는 인스턴스 해제가 발생하기 전에, 자동으로 호출된다. 해제자를 스스로 호출하는건 허용되지 않는다.

슈퍼클래스의 해제자는 서브클래스에 상속되고, 슈퍼클래스 해제자는 서브클래스 해제자 구현의 끝에서 자동으로 호출된다.

슈퍼클래스 해제자는 항상 호출된다, 서브클래스가 해제자를 만들지 않았다라도.

 

Because an instance is not deallocated until after its deinitializer is called, a deinitializer can access all properties of the instance it is 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:

여기 실제 해제자의 예제가 있다.

이 예제는 간단한 게임을 위하여 Bank 와 Player라는 2개의 새로운 타입을 정의한다.

Bank 클래스는 10,000 개의 코인보다 결코 많이 유통될수 없는 통화를 관리한다.

게임에는 하나의 Bank만 존재할수 있어서,

Bank는 현재 상태를 저장하고 관리하기 위해 type 속성과 type 메소드를 구현하였다.

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 속성에 현재 코인의 숫자를 가지고 추적한다.

또한 두개의 메소드 -distribute(coins:) 와 receive(coins:)-로 코인의 분배와 수집을 처리한다.

 

The distribute(coins:) method checks that there are enough coins in the bank before distributing them. If there are not 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:) 메소드는 분배하기 전에 은행에 충분한 코인이 있는지 검사한다.

코인이 충분하지 않다면, 요청한 숫자보다 적은 숫자를 리턴한다 (은행에 코인이 하나도 없다면 0을 리턴)

제공된 코인의 실제 숫자를 나타내는 정수형 값을 리턴한다.

 

The receive(coins:) method simply adds the received number of coins back into the bank’s coin store.

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:

receive(coins:) 메소드는 단순히 입력받은 코인의 숫자를 뱅크의 coin 저장소에 더한다.

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 인스턴스는 bank 초기화에서 받은 특정한 수의 코인을 할당하는걸로 초기화가 시작되지만,

만약 은행에 충분한 코인이 없다면 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 are 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 is currently a player in the game.

새로운 Player 인스턴스가 생성되면서 100코인을 요청하였다.

Player 인스턴스는 playerOne 이라는 optional Player 변수에 저장된다.

여기서 optional 변수를 사용한 이유는 선수가 언제든지 게임을 떠날수 있기 때문이다.

optional 은 현재 선수가 게임에 있는지 여부를 추적할수 있게 한다.

 

Because playerOne is an optional, it is qualified with an exclamation mark (!) when its coinsInPurse property is accessed to print its default number of coins, and whenever its win(coins:) method is called:

playerOne 이 optional 이기 때문에 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.

여기서 선수는 2000 코인을 땄다. 선수의 지갑은 현재 2100 코인이 있고, 은행에는 겨우 7900 코인이 남았다.

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 is 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.

선수가 이제 게임을 떠났다. 이것은 optional playerOne 변수에 nil을 넣어서 나타내고, "Player instance가 없음" 을 뜻한다.

이때 Player 인스턴스를 향하는 playerOne 변수의 참조는 없어진다.

Player 인스턴스를 참조하는 다른 속성이나 변수도 없어서 메모리를 청소하기 위해 해제된다.

이런것들이 발생하기 직전에 해제자가 자동으로 호출되고, 코인은 은행으로 반환된다.

반응형

'iOS 초보' 카테고리의 다른 글

[swift5.1번역] 17.Error Handling  (0) 2019.11.14
[swift5.1번역] 16.Optional Chaining  (0) 2019.10.11
[swift5.1번역] 14.Initialization  (0) 2019.09.04
[swift5.1번역] 13.Inheritance  (0) 2019.08.27
[swift5.1번역] 12.Subscripts  (0) 2019.08.21
Posted by 돌비
,