《浅入浅出Swift》Automatic Reference Counting 自动引用计数

####ARC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

//ARC机制会跟踪每一个实例正在被多少属性,常量和变量所引用,只要这个实例的引用数不为0,那么这个实例就不会被销毁。那么它的deinit也不会被调用
//实例之间的循环引用是怎么发生的。如果消除循环引用导致内存泄露

class Person {
let name : String
init (name : String) {
self.name = name
println("\(name) is being initialized")
}
deinit {
println("\(name) is being deinitialized")
}
}

var reference1:Person?
var reference2:Person?
var reference3:Person?

reference1 = Person(name: "John Appleseed")
reference2 = reference1
reference3 = reference1

reference1 = nil
reference2 = nil
reference3 = nil

}

func swiftARCMethodTwo() {
//Strong Reference Cycles Between Class Instances


class Person {
let name : String
init (name : String){
self.name = name
}

var apartment: Apartment?
deinit {
// apartment = nil;
println("\(name) is being deinitialized")
}
}

class Apartment{
let number : Int
init (number : Int){
self.number = number
}
weak var tenant : Person?
deinit {
// tenant = nil;
println("Apartment #\(number) is being deinitialized")
}
}
//上2个类分别都有另一个类的optional类型的变量。结果就是互相持有对方
//在ARC中,当把John和number73都赋值为nil时,看似断了2个引用,但在实例中,还有apartment和tenant2个引用没断,于是,把释放写入deinit中
//deinit并不会被调用。因为ARC中只有引用计数到0时,deinit才会被调用
//为了解决上面的循环引用,引入了关键字weak
var john : Person?
var number73 : Apartment?
john = Person(name: "John Appleseed")
number73 = Apartment(number: 73)

john!.apartment = number73
number73!.tenant = john

// john number73
// \strong \strong
// name:John Appleseed --->strong number:73
// apartmen<Apartment 实例> <---weak tenant:<Person 实例>
//引入了weak引用不会阻止ARC回收实例,也就是说,一个实例,如果没有被强引用,再多的引用持有它的话,它依然可以被释放。


//无主引用,Unowned References
//weak是给optional类型用的(!?),而unowned是给非可选型用的
class Customer{
let name :String
var card : CreditCard?
init (name : String){
self.name = name
}

deinit {
println("\(name) is being deinitialized")
}
}
class CreditCard{
let number : UInt64
unowned let customer : Customer
// weak var customer : Customer?
init (number : UInt64 , customer : Customer){
self.number = number
self.customer = customer
}
deinit {
println("Card #\(number) is being deinitialized")
}
}
var johnOne : Customer?
johnOne = Customer(name: "John Appleseed")
johnOne!.card = CreditCard(number: 1234_5678_9012_3456, customer: johnOne!)


//闭包导致的循环强引用,Strong Reference Cycles for Closures
/*
class HTMLElement{
let name: String
let text: String?
//闭包
lazy var asHTML: () -> String = {
// [unowned self] in
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}

init(name: String, text: String? = nil) {
self.name = name
self.text = text
}

deinit {
println("\(name) is being deinitialized")
}
}
*/

Reference

坚持原创技术分享,您的支持将鼓励我继续创作!
0%