加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift - 内存泄露原因(循环强引用)及解决办法

发布时间:2020-12-14 07:14:13 所属栏目:百科 来源:网络整理
导读:Swift使用自动引用计数(ARC)来管理应用程序的内存使用。在大多是情况下,并不需要考虑内存的管理。当实例不再需要的时候,ARC会自动释放这些实例所使用的内存。 但ARC并不是绝对安全的。下面两种情况会发生内存泄露。 1,类实例之间的循环强引用 两个类实
Swift使用自动引用计数(ARC)来管理应用程序的内存使用。在大多是情况下,并不需要考虑内存的管理。当实例不再需要的时候,ARC会自动释放这些实例所使用的内存。
但ARC并不是绝对安全的。下面两种情况会发生内存泄露。

1,类实例之间的循环强引用
两个类实例都有一个强引用指向对方,这样的情况就是强引用循环,从而导致内存泄露。
class Teacher {
var tName : String
student : Student ?
init (name: String ){
tName = name
println ( "老师(tName)实例初始化完成" )
}
deinit{
"老师(tName)实例反初始化完成" )
}
}
{
sName : String
teacher : ?
){
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,闭包引起的循环强引用
将一个闭包赋值给类实例的某个属性,并且这个闭包体中又使用了实例,也会发生强引用循环。
JsonElementletname:jValue:lazyasJson:() ->= {
if text = self .jValue {
return "(self.name):(text)"
} else {
"text is nil"
}
}
,text: ){
.name = name
.jValue = text
"初始化闭包" )
}
deinit{
"闭包释放" )
}
//开始测试
p: ? = "p" "hangge.com" (p!.asJson())
p = nil
//测试结果(deinit未调用,则内存泄露)
初始化闭包
p:hangge.com

解决办法:使用闭包捕获列表
当闭包和实例之间总是引用对方并且同时释放时,定义闭包捕获列表为无主引用。但捕获引用可能为nil时,定义捕获列表为弱引用。弱引用通常是可选类型,并且在实例释放后被设置为nil。
[unowned]in//使用无主引用来解决强引用循环
.jValue {
"(self.name):(text)"
{
"text is nil"
){
.name = name
.jValue = text
)
}
deinit{
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读