Swift: Strong, Weak, Unowned
Strong, Weak, Unowned Swift의 메모리 관리 시스템에서 참조를 정의할 때 사용되는 키워드 순환 참조 A가 B를 참조하고 B가 A를 참조하는 경우 같이 두 객체가 서로를 참조하면 순환 참조가 발생한다. 순환 참조가 발생하면 ARC의 Reference
Strong, Weak, Unowned
- Swift의 메모리 관리 시스템에서 참조의 유형을 정의할 때 사용되는 키워드
순환 참조
- A가 B를 참조하고 B가 A를 참조하는 경우 같이 두 객체가 서로를 참조하면 순환 참조가 발생한다.
- 순환 참조가 발생하면 ARC의 Reference Count가 절대 0이 되지 않아 메모리에서 해제되지 않고 메모리 누수(Memory Leak)가 발생한다.
class ClassA {
var instanceB: ClassB?
deinit {
print("ClassA Deinitialized")
}
}
class ClassB {
var instanceA: ClassA?
deinit {
print("ClassB Deinitialized")
}
}
var instanceA: ClassA? = ClassA()
var instanceB: ClassB? = ClassB()
// 서로의 인스턴스 참조
instanceA?.instanceB = instanceB
instanceB?.instanceA = instanceA
// nil이 되었지만 참조가 해제되지 않아 순환 참조 발생
instanceA = nil
instanceB = nil
Strong(강한 참조)
- 기본적인 참조 유형으로 별도의 지정자를 사용하지 않으면
strong참조이다. - Reference Count를 1 증가시켜, 객체를 참조하고 있으면 해당 객체는 메모리에서 해제되지 않는다.
class Person {
var pet: Pet?
}
class Pet {
var owner: Person?
}
let snack = Person()
let cream = Pet()
snack.pet = cream
cream.owner = snack
// 순환 참조가 발생하여 snack과 cream 객체는 메모리에서 해제되지 않는다.

Weak(약한 참조)
- 객체의 Reference Count를 증가시키지 않는다.
weak참조를 통해 참조되는 객체가 없어지면 자동으로nil이 되기 때문에,weak참조는 항상 옵셔널 타입이어야 한다.
class Person {
var pet: Pet?
}
class Pet {
weak var owner: Person?
}
let snack = Person()
let cream = Pet()
snack.pet = cream
cream.owner = snack
// cream 객체가 메모리에서 해제되면 cream.owner는 자동으로 nil이 된다.

Unowned(미소유 참조)
- 객체의 Reference Count를 증가시키지 않는다.
unowned참조는 참조하는 대상이 항상 메모리에 존재할 것이라는 확신이 있을 때 사용하기 때문에 옵셔널 타입이 될 수 없다.- 참조되는 객체가 메모리에서 해제되어도 해당 참조를 계속 하려하기 때문에 런타임 오류가 발생한다.
class Person {
var pet: Pet?
}
class Pet {
unowned var owner: Person
init(owner: Person) {
self.owner = owner
}
}
let snack = Person()
let cream = Pet(owner: snack)
snack.pet = cream
// snack 객체가 메모리에서 해제되고 이후에 cream.owner에 접근하려고 시도하면 런타임 오류가 발생한다.
