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
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
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
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