클래스의 인스턴스가 강한 참조가 없는 지점에 도달하지 않는, 쉽게 말하면 인스턴스를 더 이상 사용하지 않아도 참조를 유지하는 코드를 작성 가능한데 이것을 강한 참조 사이클(Strong Referencing Cycle)이라고 한다. 이는 클래스 간 일부 관계를 강한 참조 대신 약한 또는 미소유 참조로 정의해서 강한 참조 사이클을 해결할 수 있다.
class Person {
let name : String
init(name : String) {
self.name = name
}
var apartment : Apartment?
deinit {
print("\(name) is deinit!")
}
}
//사람은 항상 아파트를 가지는 건 아니므로 옵셔널이다.
class Apartment {
let unit : String
init(unit : String) {
self.unit = unit
}
var tenant : Person?
deinit {
print("\(unit) is being deinit")
}
}
//두 클래스 모두 클래스 인스턴스가 해제되는 것을 캐치하기 위해 해제자를 입력한다.
// 이어지는 코드는 Apartment와 Person 인스턴스를 설정할 두개의 옵셔널 타입 변수를 생성한다.
var john : Person?
var unit4A : Apartment?
//현재 위에서는 인스턴스가 생성되지 않았으며 이어지는 코드에서
// 인스턴스를 생성하고 변수에 할당한다.
john = Person(name : "John")
unit4A = Apartment(unit : "4A")
//다음과 같은 경우 john은 Person에 대한 강한참조를 가지며,
//unit4A는 Apartment에 대한 강한 참조를 가진다.
//이어지는 코드에서는 옵셔널 강제 언래핑을 통해서 해당 인스턴스의 프로퍼티에 접근한다.
//그러면 이번에는 상호 클래스 간의 강한 참조사이클이 발생한다.
john!.apartment = unit4A
unit4A.tenant = john
//이렇게 되면 이제 Person인스턴스와 Apartment인스턴스 사이에 강한 참조사이클이 발생한다.
john = nil
unit4A = nil
//메모리 누수를 유발한다.