zoukankan      html  css  js  c++  java
  • Swift

    Swift使用自动引用计数(ARC)来管理应用程序的内存使用。在大多是情况下,并不需要考虑内存的管理。当实例不再需要的时候,ARC会自动释放这些实例所使用的内存。

    但ARC并不是绝对安全的。下面两种情况会发生内存泄露。

    1,类实例之间的循环强引用
    两个类实例都有一个强引用指向对方,这样的情况就是强引用循环,从而导致内存泄露。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    class Teacher {
        var tName : String
        var student : Student?
         
        init(name:String){
            tName = name
            println("老师(tName)实例初始化完成")
        }
         
        deinit{
            println("老师(tName)实例反初始化完成")
        }
    }
     
    class Student {
        var sName : String
        var teacher : Teacher?
         
        init(name:String){
            sName = name
            println("学生(sName)实例初始化完成")
        }
         
        deinit{
            println("学生(sName)实例反初始化完成")
        }
    }
     
    //测试开始
    var teacher:Teacher?
    var student:Student?
    teacher = Teacher(name: "李老师")
    student = Student(name: "刘同学")
    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的实例释放后才可以回收。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    class Teacher {
        var tName : String
        weak var student : Student?
         
        init(name:String){
            tName = name
            println("老师(tName)实例初始化完成")
        }
         
        deinit{
            println("老师(tName)实例反初始化完成")
        }
    }
     
    class Student {
        var sName : String
        var teacher : Teacher?
         
        init(name:String){
            sName = name
            println("学生(sName)实例初始化完成")
        }
         
        deinit{
            println("学生(sName)实例反初始化完成")
        }
    }


    2,闭包引起的循环强引用 

    将一个闭包赋值给类实例的某个属性,并且这个闭包体中又使用了实例,也会发生强引用循环。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    class JsonElement{
        let name:String
        let jValue:String?
         
        lazy var asJson:() -> String = {
            if let text = self.jValue {
                return "(self.name):(text)"
            }else{
                return "text is nil"
            }
        }
         
        init(name:String, text:String){
            self.name = name
            self.jValue = text
            println("初始化闭包")
        }
         
        deinit{
            println("闭包释放")
        }
    }
     
    //开始测试
    var p:JsonElement? = JsonElement(name: "p", text: "hangge.com")
    println(p!.asJson())
    p = nil
     
    //测试结果(deinit未调用,则内存泄露)
    初始化闭包
    p:hangge.com


    解决办法:使用闭包捕获列表

    当闭包和实例之间总是引用对方并且同时释放时,定义闭包捕获列表为无主引用。但捕获引用可能为nil时,定义捕获列表为弱引用。弱引用通常是可选类型,并且在实例释放后被设置为nil。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    class JsonElement{
        let name:String
        let jValue:String?
         
        lazy var asJson:() -> String = {
            [unowned self] in //使用无主引用来解决强引用循环
            if let text = self.jValue {
                return "(self.name):(text)"
            }else{
                return "text is nil"
            }
        }
         
        init(name:String, text:String){
            self.name = name
            self.jValue = text
            println("初始化闭包")
        }
         
        deinit{
            println("闭包释放")
        }
    }
  • 相关阅读:
    poj 1579(动态规划初探之记忆化搜索)
    hdu 1133(卡特兰数变形)
    CodeForces 625A Guest From the Past
    CodeForces 625D Finals in arithmetic
    CDOJ 1268 Open the lightings
    HDU 4008 Parent and son
    HDU 4044 GeoDefense
    HDU 4169 UVALive 5741 Wealthy Family
    HDU 3452 Bonsai
    HDU 3586 Information Disturbing
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4841131.html
Copyright © 2011-2022 走看看