weak
(optional) vs unowned
(non-optional)
weak
와 unowned
는 Strong Reference Cycle을 해결하기 위해서 사용한다.
두 방식의 차이는 optional과 non-optional의 차이이다.
weak
의 경우에는 optional을 사용해야한다. unonwed
는 값이 무조건 있다고 가정하고 사용하기 때문에 optional을 채택해서는 안된다.
다음은 weak
를 사용한 코드이다.
class Company {
let name: String
weak var car: Car?
init(name: String) {
self.name = name
print("Company Init")
}
deinit { print("Company Deinit") }
}
class Car {
let name: String
var company: Company?
init(name: String) {
self.name = name
print("Car Init")
}
deinit { print("Car Deinit") }
}
var k8: Car? = .init(name: "k8") // Car Init
var kia: Company? = .init(name: "KIA") // Company Init
k8?.company = kia
kia?.car = k8
k8 = nil // Car Deinit
kia?.car // nil
Company(kia)
와 Car(k8)
두개의 class가 서로를 property로 가리키고 있는 상태에서, Car
을 해제한 후 Company
의 property car
을 출력해보니 nil
이 출력되는 것을 볼 수 있다.
weak
는 기본적으로 가리키던 instance가 메모리에서 해제될 경우 nil이 할당된다. 따라서 Company(kia)
의 property car
이 가리키던 Car(k8)
이 해제되자 car
에는 nil이 할당 된 것이다.
그렇다면 위의 코드에 weak
를 unowned
로 바꾸면 어떻게 될까?
class Company {
let name: String
unowned var car: Car?
init(name: String) {
self.name = name
print("Company Init")
}
deinit { print("Company Deinit") }
}
class Car {
let name: String
var company: Company?
init(name: String) {
self.name = name
print("Car Init")
}
deinit { print("Car Deinit") }
}
var k8: Car? = .init(name: "k8") // Car Init
var kia: Company? = .init(name: "KIA") // Company Init
k8?.company = kia
kia?.car = k8
k8 = nil // Car Deinit
kia?.car //Error
위와 같이 Error을 띄우게 된다. weak
와 달리 unowned
는 가리키던 instance가 해제되면 nil을 반환하지 않는다. 대신 해제된 메모리 주소값을 계속해서 들고 있는다. 따라서 이에 접근하려 할 경우, 다음과 같이 Error을 뿜어낸는 것이다.
이러한 이유로 unowned
는 non-optional로 설정해야한다. 다음과 같은 코드가 unowned
를 바르게 사용하는 코드이다.
class Company {
let name: String
unowned let car: Car
init(name: String, car: Car) {
self.name = name
self.car = car
print("Company Init")
}
deinit { print("Company Deinit") }
}
class Car {
let name: String
var company: Company?
init(name: String) {
self.name = name
print("Car Init")
}
deinit { print("Car Deinit") }
}
https://babbab2.tistory.com/27
http://minsone.github.io/mac/ios/rules-of-weak-and-unowned-in-swift
https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html