使用unowned
引用对象:
当对象被释放时,具有引用的另一个对象被标记为unowned
,该对象也同时被释放。但是该对象还包含对其他对象的其他引用而不标记unowned
?
class Base {
let str: String
init(str: String){
self.str = str
}
deinit {
print("leaving Base class with string, \(str).")
}
}
class Country {
let name: String
var capitalCity: City!
init(name: String, capitalName: String) {
self.name = name
self.capitalCity = City(name: capitalName, country: self)
}
deinit {
print("Leaving Country class")
}
}
class City {
let name: String
let baseClass: Base = Base(str: "ABC") // reference to other object.
unowned let country: Country
init(name: String, country: Country) {
self.name = name
self.country = country
}
deinit {
print("Leaving City class")
}
}
var hk: Country? = Country(name: "Hong Kong", capitalName: "Central")
let central = City(name: "Central", country: hk!)
let base = central.baseClass
print("here")
hk = nil
print("here")
print(base.str)
print("here")
//print:
//here
//Leaving Country class
//Leaving City class
//leaving Base class with string, ABC.
//here
//ABC
//here
此对象具有指向两个不同对象的两个属性。一个属性标记为unowned
。另一个属性未标记为unowned
。所以,我认为由于没有为其中一个属性标记unowned
,它会成为一个强大的参考。但是这个对象仍然从我的测试代码中释放出来。奇怪的是,在解除分配后,我仍然可以访问该物业。为什么?以及unowned
如何运作?我应该如何标记它?
答案 0 :(得分:2)
class Country {
...
init(name: String, capitalName: String) {
...
self.capitalCity = City(name: capitalName, country: self) // <-- o_O
您看到的"leaving Base class"
与central
无关。
在Contry
的构造函数中,您创建了一个City
的新实例,因此也会创建一个新的Base
。所以被破坏的只是hk!.capitalCity.baseClass
,它与central.baseClass
无关。
这些与unowned
无关。
答案 1 :(得分:1)
让我们看看这些代码行:
var hk: Country? = Country(name: "Hong Kong", capitalName: "Central")
let central = City(name: "Central", country: hk!)
let base = central.baseClass
print("here")
hk = nil
print("here")
print(base.str)
print("here")
在第一行之后,创建了三个对象:Country
,City
和Base
。以下是参考资料:
1. Country -> City: strong
2. City -> Country: weak
3. City -> Base: strong
在第二行之后,另外两个对象被创建:另一个City
和另一个Base
。参考文献:
4. second City -> Country: weak
5. second City -> second Base: strong
好的,现在我们取消分配hk
!哪些引用将指向什么?它是2和4.这意味着我们可以忽略它们。哪个参考将被销毁?这是参考1!
现在引用1被销毁,没有强引用指向您创建的第一个城市!因此,第一个城市将被解除分配并打印信息。
在第一个城市被取消分配后,没有强引用指向您创建的第一个Base
,因此它也被解除分配,打印该消息。
您在第二行到最后一行代码中访问的是第二个城市!
这是一张图片:
虚线表示弱引用。非虚线代表强大的参考。
“第二个城市也没有强大的参考依据!为什么不解除分配?”您询问。好吧,那是因为它存储在一个名为central
的本地变量中!
PS香港不是一个国家。而中央不是它的首都。中环只是香港一个繁忙的地区。