Swift 自动引用计数(ARC)
在Swift中 使用自动引用计数(ARC)这一机制来跟踪和管理应用程序的内存
通常情况下我们不需要去手动释放内存,因为 ARC 会在类的实例不再被使用时,自动释放其占用的内存。
但在有些时候我们还是需要在代码中实现内存管理,不然就会造成内存泄露。
循环引用实例:
例一:
首先创建两个类,类结尾分别写上析构函数
析构函数: 在一个类的实例被释放之前,析构函数被立即调用。用关键字deinit来标示析构函数,类似于初始化函数用init来标示。析构函数只适用于类类型。
粗暴的总结 : 释放才会调用
//测试类1
class Person {
var tName : String
var car : Car? i
nit(name:String)
{
tName = name print("\(tName)实例化完成")
}
deinit{
print("\(tName)销毁") }
}
//测试类2
class Car {
var sName : String
var person : Person?
init(name:String)
{
sName = name print("\(sName)实例化完成")
}
deinit{
print("\(sName)销毁") }
}
//测试开始
var car:Car?
var person:Person?
car = Car(name: "大哥")
person = Person(name: "宝马")
car!.person = person
person!.car = car
person = nil
car = nil
Run:
结果:
两个类都未执行deinit函数,导致内存泄露,这个时候就需要我们自己来实现内存管理
分析:
1.首先实例化了两个类
2. 其中 Teacher类中的属性指向了 Student类
3.接着 Student类中的属性也指向了 Teacher类
4.所以造成了相互的强引用,导致内存泄露
解决循环引用的办法:
使用Weak修饰变量
OC写法:
__weak __typeof(self)weakSelf = self;
Swift写法:
weak var weakSelf = self
只需要将两个类中,其中之一的var car 或者 var person 加上 weak 就能解决循环引用的问题
当A类中包含弱引用B类的实例时,同时B类中存在强引用A类的实例时
如果A释放了,也不会影响B的释放,因为B是弱引用
但是A必须等到B释放后才能内存回收
例二:
闭包中的循环引用
将一个闭包赋值给类实例的某个属性,并且这个闭包体中又使用了实例,也会发生强引用循环。
RUN:
结果:
显而易见deinit没有调用,又造成了内存泄露
解决办法:
当闭包和实例之间总是引用对方并且同时释放时,定义闭包捕获列表为无主引用。但捕获引用可能为nil时,定义捕获列表为弱引用。弱引用通常是可选类型,并且在实例释放后被设置为nil。
以上就是解决Swift循环引用的办法啦~~~~
网友评论