美文网首页
Swift : 内存泄露原因及解决办法

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

作者: 尾声动听 | 来源:发表于2018-03-02 19:36 被阅读0次

    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 : 内存泄露原因及解决办法

          本文链接:https://www.haomeiwen.com/subject/iioaxftx.html