🔥 실전 ARC!
이번에는 ARC가 실제로 어떻게 동작하는지 살펴보도록 하겠습니다. 다음은 name
이라는 상수 저장 속성을 가진 간단한 Person
클래스를 정의한 예시 코드예요.
class Person { let name: String init(name: String) { self.name = name print("\(name) is being initialized") } deinit { print("\(name) is being deinitialized") } }
swift
Person
클래스는 인스턴스의 name
속성을 설정하고 초기화가 진행 중임을 나타내는 메시지를 출력하는 이니셜라이저를 가지고 있죠. 또한 클래스의 인스턴스가 할당 해제될 때 메시지를 출력하는 디이니셜라이저도 가지고 있습니다.
다음 코드 스니펫에서는 Person?
타입의 변수 세 개를 정의하고 있어요. 이 변수들은 이후 코드에서 새로운 Person
인스턴스에 대한 다중 참조를 설정하는 데 사용될 거예요. 이 변수들은 옵셔널 타입(Person?
, Person
이 아님)이기 때문에 자동으로 nil
값으로 초기화되며, 현재는 Person
인스턴스를 참조하지 않습니다.
var reference1: Person? var reference2: Person? var reference3: Person?
swift
이제 새로운 Person
인스턴스를 생성하여 이 세 변수 중 하나에 할당할 수 있겠죠.
reference1 = Person(name: "John Appleseed") // "John Appleseed is being initialized" 출력
swift
Person
클래스의 이니셜라이저를 호출하는 시점에 "John Appleseed is being initialized"
메시지가 출력되는 것에 주목하세요. 이는 초기화가 이루어졌음을 확인시켜 줍니다.
새로운 Person
인스턴스가 reference1
변수에 할당되었기 때문에, 이제 reference1
에서 새로운 Person
인스턴스로의 강한 참조가 생겼어요. 최소한 하나의 강한 참조가 있기 때문에 ARC는 이 Person
이 메모리에 유지되고 할당 해제되지 않도록 합니다.
동일한 Person
인스턴스를 두 개의 다른 변수에 할당하면 해당 인스턴스에 대한 두 개의 강한 참조가 추가로 설정됩니다.
reference2 = reference1 reference3 = reference1
swift
이제 이 단일 Person
인스턴스에 대해 세 개
의 강한 참조가 있게 되었네요.
두 개의 변수에 nil
을 할당하여 이 강한 참조 중 두 개(원래 참조 포함)를 끊으면, 하나의 강한 참조만 남게 되고 Person
인스턴스는 할당 해제되지 않아요.
reference1 = nil reference2 = nil
swift
ARC는 세 번째이자 마지막 강한 참조마저 끊어질 때까지 Person
인스턴스를 할당 해제하지 않습니다. 그 시점이 되어야 Person
인스턴스를 더 이상 사용하지 않는다는 것이 명확해지기 때문이죠.
reference3 = nil // "John Appleseed is being deinitialized" 출력
swift
이렇게 ARC는 강한 참조의 수를 추적하여 인스턴스의 수명을 관리합니다. 강한 참조가 모두 사라지면 ARC는 해당 인스턴스가 더 이상 필요하지 않다고 판단하고 메모리에서 해제하는 거예요.
강한 참조의 수에 따른 인스턴스 해제 과정을 시각적으로 나타내면 다음과 같습니다:
이처럼 ARC는 참조 횟수를 세어 메모리를 자동으로 관리해 줍니다. 개발자가 메모리 관리에 신경 쓰지 않아도 되는 편리한 방식이라고 할 수 있겠네요!