-
Notifications
You must be signed in to change notification settings - Fork 5
Strong Reference Cycle
- 두 클래스 인스턴스가 서로 강력 참조를 쥐고 있다면, 각 인스턴스는 서로 살게 유지한다.
예제
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
deinit { println("\(name) is being deinitialized") }
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
var tenant: Person?
deinit { println("Apartment #\(number) is being deinitialized") }
}
각자의 클래스는 서로를 속성으로 옵셔널 타입으로 가진다. 아래처럼 인스턴스를 초기화 한다고 가정해보자.
var john: Person?
var number73: Apartment?
john = Person(name: "John")
number73 = Apartment(number: 73)
두 인스턴스가 만들어지고 할당 된 후에 강력 참조가 어떻게 보이는지를 나타낸 그림이다.
이제 두 인스턴스를 연결하도록 Person는 apartment를 가지고, apartment는 tenant를 가지도록 한다. 느낌표를 사용하여 옵셔널 변수인 john과 number73를 언래핑하고 인스턴스에 접근하여 각 인스턴스의 속성에 설정한다.
john!.apartment = number73
number73!.tenant = john
이 다음 두 객체를 nil로 설정한 후 강력 참조가 어떻게 보이는지 알아보자.
john = nil
number73 = nil
Person 인스턴스와 Apartment 인스턴스 간의 강력 참조는 끊어지지 않고 남아있는 모습이다.
- 약한 참조 (
Weak Reference
)-
약한 참조는 인스턴스가 다른 인스턴스 참조를 강력하게 유지하지 않으며, ARC는 참조된 인스턴스를 버리는 것을 멈추지 않게 한다.
-
약한 참조는 속성이나 변수 선언 앞에
weak
키워드를 앞에 놓는다. -
참조가 어느 순간 “값 없음”을 참조하게 될 때, 약한 참조를 사용하여 참조 순환을 피하도록 한다. 참조가 값을 항상 가진다면, 미소유 참조를 대신 사용한다. 위의 Apartment 예제에서 apartment가 특정 시점에 tenant가 없음을 가지는 것이 적합하면, 약한 참조는 참조 순환을 깨는 적합한 방법이다.
-
- 미소유 참조 (
Unowned References
)-
약한 참조와 비슷하게, 미소유 참조는 인스턴스에 대한 참조를 강하게 하지 않는다.
-
약한 참조와는 다르게 미소유 참조는 항상 값이 있음을 가정한다. 이는 미소유 참조는 항상 옵셔널이 아닌 타입으로 정의된다. 속성이나 변수 선언 전에
unowned
키워드를 붙인다. -
미소유 참조는 옵셔널이 아니기 때문에, 사용할 때마다 미소유 참조를 언래핑할 필요가 없다. 미소유 참조는 항상 직접적으로 접근하는 것이 가능하다. 그러나 ARC는 인스턴스 참조를 할당 해제할 때 참조를 nil로 설정할 수 없다. 이는 옵셔널이 아닌 타입의 변수는 nil로 설정될 수 없기 때문이다.
-
references (예제도 참고 가능)