//****************解决循环引用 的两种方式 Weak Reference , Unowned Reference
// weak 引用可以随时在实类的生命周期内 置 nil
// unowned 引用, 标志着我们明确 这个实类一旦初始化后就不会置为 nil
//----------Weak Reference---------
// 使用关键字 weak 可以让强引用 变为 弱引用. 阻止循环引用出现
// 当属性为 weak 类型, 该属性置 nil 时 观察者模式不会触发
class Person {
let name: String
init(name: String) {
self.name = name
}
var apartment:Apartment?
deinit {
print("\(name) is being deinitialized")
}
}
class Apartment{
let unit: String
init(unit: String) {
self.unit = unit
}
weak var tenant: Person?
deinit {
print("Apartment \(unit) is being deinitialized")
}
}
var john: Person?
var unit4A:Apartment?
john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil// Apartment 的Person 属性时弱引用 故可以置 nil
unit4A = nil// 引用环已经被打破, unit4A 也可以置 nil
//-------------- Unowned Reference
//和 weak 一样 unowned 也是将强引用弱化为弱引用
//和 weak 不同, unowned 的引用不能为 nil
//unowned 修饰的属性一定是 非可选值 不能置nil
// unowned 必须引用一个有内存的实类, 如果 unowned 引用指向一个已经销毁的实类, 会抛出异常
class Customer {
let name: String
var card: CreditCard?
init(name:String){
self.name = name
}
deinit {
print("\(name) is being deinitialized")
}
}
class CreditCard {
let number: UInt64
unowned let customer: Customer
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
deinit {
print("Card #\(number) is being deinitialized")
}
}
var johna: Customer?
johna = Customer(name: "John Appleseed")
johna!.card = CreditCard(number:1234_5678_9012_3456, customer: johna!)
// johna---(strong)-->CreditCard
// CreditCard -----(unowned)--->johna
johna = nil
//John Appleseed is being deinitialized
//Card #1234567890123456 is being deinitialized
// 防止循环引用的几条原则.
// 1. 属性都是可选值时, 使用 weak
// 2. 有一个属性不是可选值时, 使用 unowned
// 3. 都不是可选值时, 使用 强制解包的可选型 和 unowned 配合使用: 如下面的例子
class Country{
let name: String
var capitalCity: City!// 默认是nil
init(name: String, capitalName: String) {
self.name = name
// 因为 capitalCity 是可选值, 默认是nil, 在给 self.name 赋值之后, 可以认为 self 已经初始化成功, 所以下面的代码可以使用 self
self.capitalCity = City(name: capitalName, country: self)
}
}
class City{
let name: String
unowned let country: Country
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
var country = Country(name: "Canada", capitalName:"Ottawa")
// capitalCity 是强制解包的可选值, 所以这里不需要解包.
print("\(country.name)'s capital city is called \(country.capitalCity.name)")
Swift - 解决循环引用
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- swift使用自动引用计数(ARC)机制来跟踪和管理应用程序的内存。一般情况下,swift内存管理机制会一直起作用...
- 无主引用(unowned) 声明属性或者变量时,在前面加上unowned关键字表示这是一个无主引用,无主引用不能设...
- 弱引用(weak) 声明属性或者变量时,在前面加上weak关键字表明这是一个弱引用,弱引用会被定义为可选类型变量,...
- 无主引用以及隐式解析可选属性 两个属性都必须有值,并且初始化完成后永远不会为nil。在这种场景中,需要一个类使用无...