ARC(Automatic Reference Counting)는 애플의 메모리 관리 기술로, iOS 및 macOS에서 사용됩니다. 이는 개발자가 메모리 관리를 수동으로 처리하는 부담을 줄이고 메모리 누수를 방지하는 데 도움이 됩니다.
ARC는 객체에 대한 참조의 수를 추적하여 해당 객체가 더 이상 필요하지 않게 되면 메모리에서 자동으로 해제합니다.
각 객체는 참조 카운트를 가지며, 이 카운트는 다른 객체가 해당 객체를 참조할 때마다 증가하고, 참조가 해제되면 감소합니다.
강한 참조는 기본 참조 유형으로, 객체를 참조하면 참조 카운트가 1 증가합니다.
강한 참조를 사용하면 객체는 메모리에 유지되며, 참조 카운트가 0이 되기 전에는 해제되지 않습니다.
class MyClass {
var name: String
init(name: String) {
self.name = name
}
}
var myInstance: MyClass? = MyClass(name: "Example")
// 여기에서 myInstance는 MyClass 인스턴스에 대한 강한 참조를 가지고 있습니다.
약한 참조는 참조 카운트를 증가시키지 않으며, 일반적으로 강한 참조 순환이 발생할 가능성이 있는 경우에 사용됩니다.
약한 참조는 weak 키워드를 사용하여 선언되며, 옵셔널 타입이어야 합니다.
class AnotherClass {
weak var weakReference: MyClass?
}
var anotherInstance = AnotherClass()
anotherInstance.weakReference = myInstance
// 여기에서 anotherInstance는 myInstance에 대한 약한 참조를 가지고 있습니다.
미소유 참조는 약한 참조와 비슷하지만, 항상 값이 있어야 합니다.
미소유 참조는 unowned 키워드를 사용하여 선언됩니다.
class YetAnotherClass {
unowned var unownedReference: MyClass
init(instance: MyClass) {
self.unownedReference = instance
}
}
var yetAnotherInstance = YetAnotherClass(instance: myInstance!)
// 여기에서 yetAnotherInstance는 myInstance에 대한 미소유 참조를 가지고 있습니다.
두 객체가 서로 강한 참조를 가지고 있으면 강한 참조 순환이 발생하며, 이로 인해 메모리 누수가 발생할 수 있습니다.
이러한 순환이 발생하지 않도록 하려면 약한 또는 미소유 참조를 사용해야 합니다.
클로저는 자신이 포착한 모든 상수와 변수에 대한 강한 참조를 유지합니다. 때문에 클로저 내부에서 self를 참조하면 강한 참조 순환이 발생할 수 있습니다.
이를 방지하기 위해 클로저 내부에서 [weak self] 또는 [unowned self]를 사용하여 약한 또는 미소유 참조를 생성할 수 있습니다.