闭包的内存管理
- 为什么苹果要区分逃逸闭包和非逃逸闭包类,当然是从性能优化上考虑的。上篇文章我们说非逃逸闭包的作用域是在函数体内那函数结束后,函数体临时数据都会释放掉,对于逃逸闭包,作用域超过了函数体,那它为了防止被释放掉,它就会把自己复制一份。这样如果你在闭包里访问了当前对象的属性或者方法,那么这个闭包就对这个对象强引用,要是处理不当就会出现循环引用的危险(如果恰巧这个对象也强引用了这个闭包)。下面我们就研究一下下循环引用如何出现的。
class Person: NSObject {
var name: String?
var age: Int?
var changName: (() -> ())?
init(name: String?, age: Int?) {
self.name = name
self.age = age
}
}
let p1 = Person(name: "Bill", age: 15)
p1.changName = { Void in
print(p1.name ?? "Bill")
}
p1.changName!()
- 我们看到P1对闭包进行了强引用,然后闭包里又使用了p1.name这样闭包又对p1进行了一次强引用
QQ20170316-152929@2x.png
- 如何解决这种强引用类,我们要使用[weak 该引用对象]
p1.changName = {[weak p1] Void in
print(p1?.name ?? "Bill")
}
p1.changName!()
QQ20170316-153027@2x.png
*来画个牛逼的图看看
QQ20170316-154213@2x.png
- 总上所属不是闭包里一定要使用[weak ],而是你要看看这个闭包里使用了该对象的属性和方法没,如果使用了对不起,您造成了循环引用,请处理。如果查看项目是否有循环引用的问题。请自行百度吧!
造成循环引用的还有其他几种情况,解决循环引用的方法也不止这一种,有时间写一篇介绍循环引用的文章吧