swift 循环强引用

前端之家收集整理的这篇文章主要介绍了swift 循环强引用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
Swift使用自动引用计数(ARC)来管理应用程序的内存使用。在大多是情况下,并不需要考虑内存的管理。当实例不再需要的时候,ARC会自动释放这些实例所使用的内存。
但ARC并不是绝对安全的。下面两种情况会发生内存泄露。 @H_301_2@

@H_301_2@
1,类实例之间的循环强引用 @H_301_2@
两个类实例都有一个强引用指向对方,这样的情况就是强引用循环,从而导致内存泄露。 @H_301_2@
1 @H_301_2@
2 @H_301_2@
3 @H_301_2@
4 @H_301_2@
5 @H_301_2@
6 @H_301_2@
7 @H_301_2@
8 @H_301_2@
9 @H_301_2@
10 @H_301_2@
11 @H_301_2@
12 @H_301_2@
13 @H_301_2@
14 @H_301_2@
15 @H_301_2@
16 @H_301_2@ @H_502_50@ 17 @H_301_2@
18 @H_301_2@
19 @H_301_2@
20 @H_301_2@
21 @H_301_2@
22 @H_301_2@
23 @H_301_2@
24 @H_301_2@
25 @H_301_2@
26 @H_301_2@
27 @H_301_2@
28 @H_301_2@
29 @H_301_2@
30 @H_301_2@
31 @H_301_2@
32 @H_301_2@
33 @H_301_2@
34 @H_301_2@
35 @H_301_2@
36 @H_301_2@
37 @H_301_2@
38 @H_301_2@
39 @H_301_2@
40 @H_301_2@
41 @H_301_2@
class Teacher { @H_301_2@ @H_404_111@ var tName : String @H_301_2@
student : Student ? @H_301_2@
@H_301_2@
init (name: String ){ @H_301_2@
tName = name @H_301_2@
println ( "老师\(tName)实例初始化完成" ) @H_301_2@
} @H_301_2@
@H_301_2@
deinit{ @H_301_2@
"老师\(tName)实例反初始化完成" ) @H_301_2@
} @H_301_2@
} @H_301_2@
@H_301_2@
{ @H_301_2@
sName : String @H_301_2@
teacher : ? @H_301_2@
@H_301_2@
(name: String ){ @H_301_2@
sName = name @H_301_2@
"学生\(sName)实例初始化完成" ) @H_301_2@
} @H_301_2@
@H_301_2@
deinit{ @H_301_2@
"学生\(sName)实例反初始化完成" ) @H_301_2@
} @H_301_2@
} @H_301_2@
@H_301_2@
//测试开始 @H_301_2@
teacher: ? @H_301_2@
student: ? @H_301_2@
teacher = (name: "李老师" ) @H_301_2@
student = "刘同学" ) @H_301_2@
teacher!.student = student @H_301_2@
student!.teacher = teacher @H_301_2@
teacher = nil @H_301_2@
student = nil @H_301_2@
@H_301_2@
//测试结果(deinit未调用,则内存泄露) @H_301_2@
老师李老师实例初始化完成 @H_301_2@
学生刘同学实例初始化完成 @H_301_2@ @H_301_2@
@H_301_2@ @H_301_2@
解决办法:使用弱引用
只需要将上述例子Teacher类的student变量加上关键字weak,或者将Student类的teacher变量加上关键字weak。
当A类中包含有B类的弱引用的实例,同时,B类中存在A的强引用实例时,如果A释放,也不会影响B的释放。但A的内存回收要等到B的实例释放后才可以回收。 @H_301_2@ @H_301_2@
2 @H_301_2@
3 @H_301_2@
27 @H_301_2@
String @H_301_2@
weak } @H_301_2@ @H_301_2@
@H_301_2@ @H_301_2@
2,闭包引起的循环强引用
将一个闭包赋值给类实例的某个属性,并且这个闭包体中又使用了实例,也会发生强引用循环。 @H_301_2@
31 @H_301_2@
JsonElement let name: String @H_301_2@
jValue: lazy asJson:() -> = { @H_301_2@
if text = self .jValue { @H_301_2@
return "\(self.name):\(text)" @H_301_2@
} else { @H_301_2@
"text is nil" @H_301_2@
} @H_301_2@
} @H_301_2@
@H_301_2@
,text: ){ @H_301_2@
.name = name @H_301_2@
.jValue = text @H_301_2@
"初始化闭包" ) @H_301_2@
} @H_301_2@
deinit{ @H_301_2@
"闭包释放" ) @H_301_2@
} @H_301_2@
@H_301_2@
//开始测试 @H_301_2@
p: ? = "p" "hangge.com" (p!.asJson()) @H_301_2@
p = nil @H_301_2@
//测试结果(deinit未调用,则内存泄露) @H_301_2@
初始化闭包 @H_301_2@
p:hangge.com @H_301_2@ @H_301_2@
@H_301_2@ @H_301_2@
解决办法:使用闭包捕获列表
当闭包和实例之间总是引用对方并且同时释放时,定义闭包捕获列表为无主引用。但捕获引用可能为nil时,定义捕获列表为弱引用。弱引用通常是可选类型,并且在实例释放后被设置为nil。 @H_301_2@
23 @H_301_2@
name: jValue: asJson:() -> [ unowned ] in //使用无主引用来解决强引用循环 @H_301_2@
.jValue { @H_301_2@
"\(self.name):\(text)" @H_301_2@
{ @H_301_2@
"text is nil" @H_301_2@
@H_301_2@
){ @H_301_2@
.name = name @H_301_2@
.jValue = text @H_301_2@
) @H_301_2@
} @H_301_2@
@H_301_2@
deinit{ @H_301_2@
} @H_301_2@ @H_301_2@
@H_301_2@ @H_301_2@ @H_301_2@
原文出自: www.hangge.com 转载请保留原文链接 http://www.hangge.com/blog/cache/detail_742.html

猜你在找的Swift相关文章