Swift : 内存泄露原因及解决办法

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循环引用的办法啦~~~~

你可能感兴趣的:(Swift : 内存泄露原因及解决办法)