Swift ARC와 메모리 관리
ARC가 참조 횟수로 메모리를 관리하는 원리와 강한 참조 순환을 끊는 방법을 살펴봅니다.

Swift에서 메모리를 직접 해제하는 코드는 거의 쓰지 않는다. 편리한 이유는 ARC가 대신 참조 횟수를 관리하기 때문인데, 자동이라는 말이 모든 문제를 알아서 해결한다는 뜻은 아니다.
Reference와 Heap
Swift에서 참조(Reference) 타입의 인스턴스는 Heap 영역에 할당된다. Heap 영역에 저장된 메모리는 개발자나 메모리 관리 시스템이 명시적으로 해제하기 전까지는 계속해서 남아있기 때문에, 사용하고 난 후에는 반드시 해제해야 한다.
이전 Objective-C에서는
retain,release같은 함수들로 직접 Heap 메모리에 할당/해제를 했다.
Automatic Reference Counting
참조 타입의 Reference Count를 추적하여 메모리 할당/해제를 자동화하는 기능이다. ARC는 컴파일 타임(Compile Time)에 진행되어 코드에서 객체에 대한 참조를 생성하거나 제거할 때 적절한 retain, release 코드를 자동으로 삽입한다. 컴파일 타임에 진행되기 때문에 런 타임에 추가적인 오버헤드가 없다.
📚 Swift Documentations - Automatic Reference Counting Swift uses Automatic Reference Counting (ARC) to track and manage your app’s memory usage. In most cases, this means that memory management “just works” in Swift, and you don’t need to think about memory management yourself. ARC automatically frees up the memory used by class instances when those instances are no longer needed.
Reference Counting
인스턴스가 생성되거나 다른 객체가 해당 인스턴스를 참조하게 되면 Reference Count가 1씩 증가한다. 해당 참조가 끝나거나 인스턴스에 대한 참조를 잃게 되면 Reference Count가 1씩 감소한다. Reference Count가 0이 되면 해당 인스턴스는 더 이상 메모리에 유지될 필요가 없다는 것을 의미하여 메모리헤서 해제된다.
class Human {
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
// 인스턴스 생성으로 Reference Count가 1 증가
var snack: Human? = Human(name: "snack", age: 28) // Count(1)
// 다른 객체가 같은 인스턴스를 참조하여 Reference Count가 1 증가
var sunday: Human? = Human(name: "sunday", age: 26) // Count(2)

// 인스턴스에 대한 참조가 해제되어 Reference Count가 1 감소
snack = nil // Count(1)
// 인스턴스에 대한 참조가 해제되어 Reference Count가 1 감소
sunday = nil // Count(0)
// Reference Count가 0이 되어 메모리 해제

Strong Reference Cycle
ARC 기능의 주의사항으로 두 개 이상의 객체가 서로를 강하게(Strong) 참조하는 상황이 있다. 강한 순환 참조가 발생하면 인스턴스가 실제로 사용되지 않음에도 불구하고 Reference Count가 0이 되지 않아 메모리에서 해제되지 않는다. 이럴 경우 메모리 누수(Memory Leak)가 발생하기 때문에, weak과 unowned와 같은 키워드를 적절하게 사용하여 강한 순환 참조를 방지해야 한다.
