Skip to content

Commit b87e7ea

Browse files
committed
循环引用
1 parent 4bb12ba commit b87e7ea

File tree

2 files changed

+112
-1
lines changed

2 files changed

+112
-1
lines changed

ARC.playground/Contents.swift

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,115 @@ unit4A = nil
7676
// 解决实例之间的循环强引用
7777
// swift提供了两种办法用来解决你在使用类的属性时所遇到的循环强引用问题:弱引用和无主引用
7878
// 弱引用和无主引用允许循环引用中的一个实例引用另外一个实例而不保持强引用。
79+
// 何时使用弱引用?何时使用无主引用?
80+
// 对于生命周期中会变为nil的实例使用弱引用。相反的,对于初始化赋值后再也不会被赋值为nil的实例,使用无主引用
81+
82+
// 弱引用
83+
// 申明属性或者变量时,在前面加上weak关键字表明这是一个弱引用
84+
// 弱引用必须被声明为变量,表明其值能在运行时被修改。弱引用不能被声明为常量
85+
class PersonTwo {
86+
let name:String
87+
init(name:String) {self.name = name}
88+
var apartment:ApartmentOne?
89+
deinit {
90+
print("\(name) is being deinitialized")
91+
}
92+
}
93+
94+
class ApartmentOne {
95+
let unit:String
96+
init(unit:String) {
97+
self.unit = unit
98+
}
99+
weak var tenant:PersonTwo? // 弱引用
100+
deinit{
101+
print("\(unit) is being deinitialized")
102+
}
103+
}
104+
105+
var johnOne:PersonTwo?
106+
var unit4AOne:ApartmentOne?
107+
johnOne = PersonTwo(name: "John Appleseed")
108+
unit4AOne = ApartmentOne(unit: "4A")
109+
110+
johnOne!.apartment = unit4AOne
111+
unit4AOne!.tenant = johnOne
112+
113+
// PersonOne的实例将会被销毁
114+
johnOne = nil
115+
116+
// ApartmentOne的实例也将会被销毁
117+
unit4AOne = nil
118+
119+
120+
// 无主引用
121+
122+
// 和弱引用类似,无主引用不会牢牢保持住引用的实例。和弱引用不同的是,无主引用是永远有值的。在声明属性或者变量时,在前面加上关键字unowned表示这是一个无主引用
123+
124+
class Customer {
125+
let name:String
126+
var card:CreditCard?
127+
init(name:String) {
128+
self.name = name
129+
}
130+
deinit {
131+
print("\(name) is being deinitialized")
132+
}
133+
}
134+
135+
class CreditCard {
136+
let number: UInt64
137+
unowned let customer:Customer
138+
init(number:UInt64, customer:Customer) {
139+
self.number = number
140+
self.customer = customer
141+
}
142+
deinit {
143+
print("\(number) is being deinitialized")
144+
}
145+
}
146+
147+
var johnTwo:Customer?
148+
johnTwo = Customer(name: "John Appleseed")
149+
johnTwo!.card = CreditCard(number: 1234_9012_3456, customer: johnTwo!)
150+
151+
// 销毁顾客实例
152+
johnTwo = nil
153+
154+
155+
// 无主引用以及隐式解析可选属性
156+
// 两个属性都必须有值,并且初始化完成后永远不会为nil。在这种场景中,需要一个类使用无主属性,而另外一个类使用隐式解析可选属性。
157+
158+
class Country {
159+
let name:String
160+
var capitalCity:City!
161+
init(name:String, capitalName:String) {
162+
self.name = name
163+
self.capitalCity = City(name:capitalName,country:self)
164+
}
165+
}
166+
167+
class City {
168+
let name:String
169+
unowned let country:Country
170+
init(name:String, country:Country) {
171+
self.name = name
172+
self.country = country
173+
}
174+
}
175+
176+
var country = Country(name: "Canada", capitalName: "Ottawa")
177+
178+
// 闭包引起的循环强引用
179+
180+
181+
182+
183+
184+
185+
186+
187+
79188

80189

81190

ARC.playground/contents.xcplayground

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<playground version='5.0' target-platform='ios'/>
2+
<playground version='5.0' target-platform='ios'>
3+
<timeline fileName='timeline.xctimeline'/>
4+
</playground>

0 commit comments

Comments
 (0)