Swift使用自动引用计数(ARC)来管理应用程序的内存使用。在大多是情况下,并不需要考虑内存的管理。当实例不再需要的时候,ARC会自动释放这些实例所使用的内存。
解决办法:使用弱引用
2
2,闭包引起的循环强引用
31
解决办法:使用闭包捕获列表
23
但ARC并不是绝对安全的。下面两种情况会发生内存泄露。
1,类实例之间的循环强引用
两个类实例都有一个强引用指向对方,这样的情况就是强引用循环,从而导致内存泄露。
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
@H_502_88@
36
37
38
39
40
41
|
class
Teacher
{
var
tName :
String
student :
Student
?
init
(name:
String
){
tName = name
println
(
"老师\(tName)实例初始化完成"
)
}
deinit{
"老师\(tName)实例反初始化完成"
)
}
}
{
sName :
String
teacher :
?
(name:
String
){
sName = name
"学生\(sName)实例初始化完成"
)
}
deinit{
"学生\(sName)实例反初始化完成"
)
}
}
//测试开始
teacher:
?
student:
?
teacher =
(name:
"李老师"
)
student =
"刘同学"
)
teacher!.student = student
student!.teacher = teacher
teacher =
nil
student =
nil
//测试结果(deinit未调用,则内存泄露)
老师李老师实例初始化完成
学生刘同学实例初始化完成
|
解决办法:使用弱引用
只需要将上述例子Teacher类的student变量加上关键字weak,或者将Student类的teacher变量加上关键字weak。
当A类中包含有B类的弱引用的实例,同时,B类中存在A的强引用实例时,如果A释放,也不会影响B的释放。但A的内存回收要等到B的实例释放后才可以回收。
String
weak
}
|
2,闭包引起的循环强引用
将一个闭包赋值给类实例的某个属性,并且这个闭包体中又使用了实例,也会发生强引用循环。
JsonElement
let
name:
String
jValue:
lazy
asJson:() ->
= {
if
text =
self
.jValue {
return
"\(self.name):\(text)"
}
else
{
"text is nil"
}
}
,text:
){
.name = name
.jValue = text
"初始化闭包"
)
}
deinit{
"闭包释放"
)
}
//开始测试
p:
? =
"p"
"hangge.com"
p =
nil
//测试结果(deinit未调用,则内存泄露)
初始化闭包
p:hangge.com
|
解决办法:使用闭包捕获列表
当闭包和实例之间总是引用对方并且同时释放时,定义闭包捕获列表为无主引用。但捕获引用可能为nil时,定义捕获列表为弱引用。弱引用通常是可选类型,并且在实例释放后被设置为nil。
name:
jValue:
asJson:() ->
[
unowned
]
in
//使用无主引用来解决强引用循环
.jValue {
"\(self.name):\(text)"
{
"text is nil"
){
.name = name
.jValue = text
)
}
deinit{
}
|
原文出自: www.hangge.com 转载请保留原文链接: http://www.hangge.com/blog/cache/detail_742.html 原文链接:https://www.f2er.com/swift/324455.html