공식 문서로 공부하는 Swift (14) - 초기화 해제

ci·2020년 5월 30일
1

Deinitialization

디이니셜라이저는 클래스 인스턴스가 소멸되기 전에 즉시 호출된다. deinit 키워드를 통해 디이니셜라이저를 사용할 수 있다. 디이니셜라이저는 클래스 타입에서만 사용할 수 있다.



디이니셜라이저의 작동 방식

Swift는 인스턴스가 더 이상 필요하지 않으면 공간을 비움으로써 자동으로 소멸시킨다. Swift는 자동 참조 카운팅(ARC, Automatic Reference Counting)을 통해 인스턴스의 메모리를 관리한다. 일반적으로 인스턴스가 소멸될 때 수동으로 청소를 할 필요가 없다. 하지만 리소스를 사용하고 있을 때, 추가적인 청소 작업이 필요할 때가 있다. 예를 들어 파일을 열고 데이터를 쓰는 커스텀 클래스를 만들면, 클래스 인스턴스가 소멸될 때 파일을 닫아야 할 필요가 있다.


클래스는 최대 하나의 디이니셜라이저를 가질 수 있다. 디이니셜라이저는 매개 변수를 갖지 않으며, 소괄호를 작성하지 않는다.

deinit {
    // perform the deinitialization
}

디이니셜라이저는 인스턴스가 소멸되기 직전에 자동으로 호출된다. 수동으로 호출할 수는 없다. 자식 클래스가 상속한 부모 클래스의 디이니셜라이저는 자식 클래스의 디이니셜라이저 구현의 끝에서 자동으로 호출된다. 부모 클래스의 디이셜라이저는 자식 클래스에서 디이니셜라이저를 선언하지 않아도 항상 실행된다.

디이니셜라이저가 호출된 이후에야 인스턴스가 소멸되기 때문에, 디이니셜라이저는 인스턴스의 모든 프로퍼티에 접근할 수 있고, 프로퍼티에 기반하여 행동을 수정할 수도 있다.



디이니셜라이저의 사용

디이니셜라이저를 사용하는 예시가 있다. 이 예시는 BankPlayer 두 가지 타입을 정의한다. Bank 클래스는 통화를 관리하며, 10000 코인 이상 보유할 수 없다. 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
    }
}

Player 클래스는 게임에서의 플레이어를 묘사한다. 각 플레이어는 각 시점에서 그들의 지갑에 저장된 코인의 양을 갖고 있다.

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는 디이니셜라이저를 구현하고 있다. 여기서 디이니셜라이저는 플레이어가 가진 모든 코인을 은행에 돌려 준다.

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"

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"

플레이어가 게임을 떠나 playerOnenil을 할당하면, Player 인스턴스에 대한 참조는 끊어진다. 그리고 메모리에서 비워져 소멸된다. 이러한 일이 일어나기 전에 디이니셜라이저가 호출되어 은행에 돈을 돌려 주게 된다.

0개의 댓글