[최종 수정일 : 2018.08.31]
원문 : 애플 개발 문서 Swift 4.2 Language Guide - Deinitialization
해제(Deinitialization)
해제(deinitializer)는 클래스가 메모리 해제되기 직전에 호출됩니다. init
키워드로 초기화 하는 방법과 비슷하게, deinit
키워드로 해제를 작성합니다. 해제는 클래스 타입에서만 가능합니다.
해제 작업 방법(How Deinitialization Works)
Swift는 리소스를 확보하기 위해, 인스턴스가 더 이상 필요하지 않을때 자동으로 해제합니다. Swift는 인스턴스의 메모리 관리를 automatic reference counting(ARC)를 통해서 처리하며, 자동 참조 개수(Automatic Reference Counting)에 설명되어 있습니다. 일반적으로 인스턴스가 메모리에서 해제될때, 수동으로 정리 할 필요가 없습니다. 하지만, 리소스로 작업을 할때, 몇가지 추가적인 정리 작업이 필요할수 있습니다. 예를 들어, 파일을 열고 약간의 데이터를 작성하는 사용자정의 클래스를 생성하는 경우, 클래스 인스턴스가 메모리에서 해제되기 전에 파일을 닫을 필요가 있습니다.
클래스는 클래스당 하나의 해제(deinitializer)를 정의할 수 있습니다. 해제는 어떤 매개변수도 가지지 않고 괄호 없이 작성됩니다.
deinit {
// perform the deinitialization
}
해제(Deinitializer)는 인스턴스가 메모리에서 해제되기 전에, 자동으로 호출됩니다. 여러분이 해제를 호출하는 것은 허용되지 않습니다. 상위클래스 해제는 하위클래스에 상속되고, 상위클래스 해제는 하위클래스 해제 구현의 끝부분에서 자동으로 호출됩니다. 하위클래스가 해제를 제공하지 않더라도, 상위클래스의 해제는 항상 호출됩니다.
인스턴스는 해제가 호출될때까지 메모리에서 해제되지 않기 때문에, 해제는 인스턴스의 모든 프로퍼티를 접근할수 있수 있고 이러한 프로퍼티의 기본 동작을 수정할 수 있습니다(파일의 이름을 찾아서 닫는 것 처럼)
해제 동작(Deinitializers in Action)
다음은 해제 동작의 예제입니다. 이 예제는 단순한 게임에 대해, 2개의 새로운 타입 Bank
와 Player
를 정의합니다. Bank
클래스는 10,000
개 이상의 동전을 유통시킬수 없도록 화폐를 관리합니다. 게임에서 하나의 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
는 coinsInBank
프로퍼티로 동전의 현재 개수를 추적합니다. 또한, 동전의 인출(distribution)과 입금(collection)을 위해 2개의 메소드(distribute(coins:)
와 receive(coins:)
)를 제공합니다.
distribute(coins:)
메소드는 출금하기 전에 은행에 충분한 동전이 잇는지 확인합니다. 동전이 충분하지 못한 경우에, Bank
은 요청된 개수보다 더 작은 숫자를 반호나 합니다(은행에 남아 있는 동전이 없는 경우 0을 반환). 제공된 실제 동전의 숫자를 가리키기 위해 정수형 값을 반환합니다.
receive(coins:)
메소드는 단순히 은행의 동전 저장소에 동전의 숫자를 추가합니다.
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)
}
}
각 Player
인스턴스는 초기화하는 동안 은행에서 지정된 개수의 동전으로 시작하도록 초기화되며, 동전이 충분하지 않는 경우에 Player
인스턴스는 더 적은 개수를 받습니다.
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"
새로운 Player
인스턴스는 가능하다면 100
의 동전을 요청해서 생성됩니다. 이 Player
인스턴스는 옵셔널 Player
변수 playerOne
로 저장됩니다. 플레이어가 언제든지 게임을 떠날수 있기 때문에 , 옵셔널 변수가 사용됩니다. 옵셔널은 현재 플레이어가 게임에 있는지 추적합니다.
PlayerOne
이 옵셔널이기 때문에, win(coins:)
메소드가 호출될때마다 동전의 기본 개수를 출력하기 위해 coinsInPurse
프로퍼티를 사용할때 느낌표(!
)를 사용할수 있습니다.
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"
플레이어는 동전 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"
플레이어가 게임을 떠났습니다. 옵셔널 playerOne
변수가 nil
로 설정되며,
을 의미합니다. 이 시점에, Player
인스턴스가 없음playerOne
변수의 Player
인스턴스를 참조가 깨졌습니다. 다른 프로퍼티나 변수 없이 Player
인스턴스를 여전히 참조하고, 메모리에서 해제시키기 위해 할당된 메모리를 해제합니다. 이러한 일이 발생되기 직전에, 해제는 자동으로 호출되고, 동전은 은행으로 반환됩니다.
'Swift > Language Guide' 카테고리의 다른 글
Nested Types (0) | 2018.09.18 |
---|---|
Type Casting (0) | 2018.09.18 |
Error Handling (0) | 2018.09.18 |
Optional Chaining (0) | 2018.09.18 |
Initialization (0) | 2018.09.17 |
Inheritance (0) | 2018.08.30 |
Subscripts (0) | 2018.08.30 |
Methods (0) | 2018.08.30 |