본문 바로가기

Swift/공식문서

[Swift 공식문서 번역] ARC (Automatic Reference Counting) - 1.

 

ARC부터 Swift 공식문서를 차근차근 조금씩 번역해 보려고 한당...!!

약간의 의역이 포함될 예정..~

오역이나 업데이트가 필요한 부분은 꼭 댓글로 알려 주세요,,!!! :)

 

 

 

Automatic Reference Counting (말 그대로 참조 횟수를 자동으로 세는 것!)

객체들과 객체들 사이의 관계의 수명 모델링

 

Swift는 Automatic Reference Counting (ARC)를 통해 당신의 앱의 메모리 사용을 추적하고 관리합니다. 대부분의 경우, 이건 메모리 관리가 Swift에서 "그냥 된다"는 것을 의미하고, 메모리 관리에 신경 쓸 필요가 없다는 것을 뜻합니다. ARC는 클래스 인스턴스가 더이상 필요하지 않을 때, 그 인스턴스들이 사용하던 메모리들을 자동으로 해제해 줍니다.

 

하지만, 어떤 경우에는 ARC가 당신을 위해 메모리를 관리하려면 당신의 코드 부분들 사이의 관계에 대한 더 많은 정보가 필요합니다. 이 챕터는 그런 상황들을 설명할 것이고, 어떻게 ARC가 당신의 앱의 모든 메모리를 관리하도록 할 수 있는지 알려줄 거예요. Swift에서의 ARC 사용은 Objective-C에서의 ARC 사용을 다루는 Transitioning to ARC Release Notes에서 묘사된 접근 방식과 매우 유사합니다. 

 

참조 카운팅은 클래스의 인스턴스에만 해당됩니다. 구조체와 열거형은 참조 타입이 아니라 값 타입이고, 참조 방식으로 저장되거나 전달되지 않습니다.

 

 

 

 

 

How ARC Works

당신이 클래스의 새로운 인스턴스를 만들 때마다, ARC는 그 인스턴스의 정보를 저장하기 위해 메모리의 일부분을 할당합니다. 그 메모리는 그 인스턴스와 관련된 저장 프로퍼티의 값들과 함께, 인스턴스의 타입에 대한 정보도 갖고 있게 됩니다. 

 

추가적으로, 인스턴스가 더이상 필요하지 않게 되면, ARC는 그 인스턴스가 쓰던 메모리를 해제해서 다른 용도로도 사용될 수 있도록 합니다. 이것은 클래스 인스턴스들이 더이상 필요하지 않을 때 메모리를 차지하지 않도록 해 주죠.

 

하지만, ARC가 만약 아직 사용중인 인스턴스를 메모리에서 해제해 버린다면, 더이상 그 인스턴스의 프로퍼티에 접근하거나, 그 인스턴스의 메서드를 호출할 수 없을 거예요. 만약 그 인스턴스에 접근하려고 한다면, 당신의 앱은 아마 충돌이 일어날 거예요.(튕길 거라는 말)

 

인스턴스가 아직 필요할 때는 인스턴스가 사라지지 않도록 하기 위해서, ARC는 몇 개의 프로퍼티, 상수, 변수가 현재 각 인스턴스를 참조하고 있는지 추적합니다. ARC는 인스턴스에 참조하는 게 단 하나라도 존재한다면 그 인스턴스를 메모리에서 해제하지 않을 겁니다.

 

이것이 가능하도록 하기 위해, 당신이 클래스 인스턴스를 프로퍼티/상수/변수에 할당할 때마다, 그 프로퍼티/상수/변수는 그 인스턴스를 강한 참조합니다. 이 참조는 해당 인스턴스를 견고하게 붙들고 있게 되고, 참조하는 한 메모리에서 해제되지 않도록 하기 때문에 "강한" 참조라고 불립니다.

 

 

 

 

 

ARC in Action

Automatic Reference Counting이 어떻게 동작하는지에 대한 예시가 하나 있습니다. 이 예시는 name이라는 저장 상수 프로퍼티를 정의하는 간단한 클래스 Person으로 시작합니다.

class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }
    deinit {
        print("\(name) is being deinitialized")
    }
}

Person 클래스는 이니셜라이저(생성자)가 있는데, 이 이니셜라이저는 인스턴스의 name 프로퍼티를 지정하고, 초기화가 진행중이라는 것을 알려주는 메시지를 출력합니다. Person 클래스는 디이니셜라이저(소멸자)도 있는데, 그것은 클래스의 인스턴스가 메모리에서 해제될 때 메시지를 출력합니다.

 

 

다음 코드 스니펫은 Person? 타입의 변수 세 개를 정의하는데, 이후에 나올 코드들에서 하나의 새로운 Person 인스턴스를 여러 번 참조할 때 사용될 겁니다. 이 변수들은 옵셔널 타입이기 때문에(Person이 아니라 Person?이니까), 자동으로 nil로 초기화가 되고, 현재는 Person 인스턴스를 참조하지 않습니다.

var reference1: Person?
var reference2: Person?
var reference3: Person?

 

 

이제 새로운 Person 인스턴스를 만들고 이 변수 세 개 중 하나에 할당할 수 있습니다.

reference1 = Person(name: "John Appleseed")
// "John Appleseed is being initialized" 출력

 

Person 클래스의 이니셜라이저를 호출하는 시점에 "John Appleseed is being initialized"가 출력되는 것에 주목하세요. 초기화가 진행되었다는 걸 알 수 있습니다.

 

새로운 Person 인스턴스가 reference1 변수에 할당되었기 때문에, 이제 reference1이 그 새로운 Person 인스턴스를 강한 참조합니다. 적어도 하나의 강한 참조가 있으니, ARC는 이 Person(인스턴스)이 반드시 메모리에 유지되고 해제되지 않도록 해 줍니다.

 

 

같은 Person 인스턴스를 두 변수에 더 할당시키면, 그 인스턴스를 강한 참조하는 게 두 개 더 생깁니다.

reference2 = reference1
reference3 = reference1

 

이제 이 Person 인스턴스 하나에 강한 참조가 3 개 있네요.

 

 

만약 변수들 중 2 개에 nil을 할당함으로써 강한 참조들 중 2 개를 끊으면(처음 참조한 것 포함), 하나의 강한 참조만이 남게 되고, Person 인스턴스는 메모리에서 해제되지 않습니다.

reference1 = nil
reference2 = nil

 

 

더이상 그 Person 인스턴스를 사용하지 않는다는 게 분명한 순간, 즉 마지막 세 번째 강한 참조가 끊어질 때까지, ARC는 이 Person 인스턴스를 메모리에서 해제하지 않습니다. 

reference3 = nil
// "John Appleseed is being deinitialized" 출력