ARC로 인해 스위프트에서는 메모리에 대한 특별한 관리 없이도 "그냥 작동하는" 경우가 대부분이다. ARC는 인스턴스들이 더이상 사용되지 않을 때 자동으로 메모리를 비워준다.
하지만, 몇몇 경우에 ARC는 메모리를 관리하기 위해서 코드에 대한 어떤 정보를 필요로 한다.
*레퍼런스 카운팅은 클래스의 인스턴스에만 적용되는 개념이다 - 열거형 및 구조체는 값 타입이므로.
class Person {
let name: String
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
var reference1: Person?
var reference2: Person?
var reference3: Person?
var reference: Person?
와 같이 옵셔널로 어떤 인스턴스를 만들면 초깃값은 nil이며, Person
클래스를 참조하지 않는다. 이 상태에서, 아직 인스턴스는 initialize되지 않음.
reference1 = Person(name: "John Appleseed")
// Prints "John Appleseed is being initialized"
이 상태일 때, reference1
→ Person
인스턴스 이렇게 강한 참조
가 생긴다.
최소 하나의 강한 참조
가 있으므로, ARC가 이제 메모리상에 Person이 유지되며 해제되지 않음을 보장해준다.
reference2 = reference1
reference3 = reference1
이러면 Person
인스턴스에 대한 총 3개의 강한 참조
가 있는 상태이다.
reference1 = nil
reference2 = nil
이렇게 셋 중 두개의 강한 참조를 없애도, 아직 하나가 남았기에 Person
인스턴스는 아직 메모리에서 해제되지 않는다.
reference3 = nil
// Prints "John Appleseed is being deinitialized"
이렇게 마지막 강한 참조
관계까지 없애주면 더이상 Person
인스턴스가 사용되지 않는 상태이기에 ARC가 Person
인스턴스를 메모리에서 해제한 것을 확인할 수 있다.
Swift에서 사용되는 메모리 관리 방식인 ARC는 흔히 Garbage Collector 와 비교되는 개념이다.
ARC는 컴파일시 컴파일러가 코드의 요소요소에 적절히 메모리 해제 코드를 끼워넣어 주는 것이고,
GC는 런타임시 사용되지 않는 인스턴스가 있는지 탐색하여 해제해준다.
ARC는 메모리가 언제 해제될지에 대한 규칙
이다. 그 규칙에 따라 컴파일시 메모리 해제 시점이 정해지는 것.
그렇기에 규칙을 이해하고 코드를 작성할 필요가 있다.