zoukankan      html  css  js  c++  java
  • 内存管理:内存泄漏和空悬指针

    ********内存管理基础*********************

    内存管理:针对的是实例的内存占用的管理(放在堆里面)

    实例:1:由class类型构建的实例,2:闭包对象

     内存管理技术:ARC:Automatic Reference Count

    自动:由语言本身帮我们销毁内存,不需要你手动销毁,

    比如在c中就调用dealloc()

    引用:let p = Person()  p就是对Person()这个对象的一个引用

    计数: let p = Person() //一个

    / / let pp = p   //二个

    利用析构函数来判断是否销毁

    class Person {
        var name: String
        init(name: String ) {
            self.name = name
        }
        deinit {
            print("(name) person deinit")
        }
    }
    
    var p: Person? = Person(name: "david")
    //p = nil
    var pp = p
    p = nil
    pp = Person(name: "banzhang")
    pp = nil

    引用增加:一般是把一个对象不断的赋值给变得变量或属性等

    引用减少:手动把变量等得值赋值为nil活着让其引用一个新的对象,活着函数执行完毕(比如下面)

    
    
    class Person {
        var name: String
        init(name: String ) {
            self.name = name
        }
        deinit {
            print("(name) person deinit")
        }


    func testArc() {
         var p = Person(name: "chenhe")
         print(p.name) 
    }
    
    testArc() //系统自动调用deinit
    
    

    *************循环引用*************

    循环引用的阐述

    class Student {
        var name: String
        var t: Teacher?
        init(name: String) {
            self.name = name
        }
        deinit {
            print("(name) student deinit")
        }
    }
    
    class Teacher {
        var name: String
        var banzhang: Student?
        init(name: String) {
            self.name = name
        }
        deinit {
            print("(name) teacher deinit")
        }
    }
    var teacher:Teacher? = Teacher(name: "cheng")
    var bc:Student? = Student(name: "ling")
    teacher?.banzhang  = bc
    bc?.t = teacher
    
    teacher = nil 
    bc?.t = nil
    bc = nil  //因为是两个强引用,所以还要bc?,t=nil

    //循环引用的解决办法:weak(弱引用)和unowned(非拥有)

     循环引用:为了解决内存泄露与空悬指针的问题

    解决空悬指针的办法只有两种:一种是把其值赋值为nil,另一种是把其指向另外的新对象(这种方法不可行)

    在swift中,赋值为nil只有用?或!声明的类成员才行

    严格来说,就只有3种情况需要考虑

    **********第一种情况:两边都是?

    class Student {
        var name: String
        var t: Teacher?
        init(name: String) {
            self.name = name
        }
        deinit {
            print("(name) student deinit")
        }
    }
    
    class Teacher {
        var name: String
        weak var banzhang: Student?
        init(name: String) {
            self.name = name
        }
        deinit {
            print("(name) teacher deinit")
        }
    }
    var teacher:Teacher? = Teacher(name: "cj")
    var bc:Student? = Student(name: "yeweidong")
    teacher?.banzhang  = bc
    bc?.t = teacher
    
    bc = nil
    teacher = nil //因为teacher是weak

    第二种情况:一边为可空类型,一边为非可空类型(unowned)

    class Student2 {
        var name: String
        var t: Teacher2?
        init(name: String) {
            self.name = name
        }
        deinit {
            print("(name) student deinit")
        }
    }
    
    class Teacher2 {
        var name: String
        //unowned修饰在非可选类型上,不能用weak,weak只能用在可选类型
        unowned var banzhang: Student2
        init(name: String,stu: Student2) {
            self.name = name
            self.banzhang = stu
        }
        deinit {
            print("(name) teacher deinit")
        }
    }
    var s1: Student2? = Student2(name: "ch")
    var teac: Teacher2? = Teacher2(name: "david", stu: s1!)
    s1?.t = teac
    teac?.banzhang = s1!
    
    s1 = nil 

     第三种情况

    //第三种情况:两边都是非可空类型
    
    class Student3 {
        var name: String
        var t: Teacher3!  //nil
        init(name: String,teacherName: String) {
            
            self.name = name//这行代码运行后name有值,然后t有nil,所以self就可以用
            self.t = Teacher3(name: teacherName, stu: self)
        }
        deinit {
            print("(name) student deinit")
        }
    }
    
    class Teacher3 {
        var name: String
        
        //     var banzhang: Student3 = Student3(name: "xuesheng", teacher: self)//不能用self,除非lazy
        unowned var banzhang: Student3
        init(name: String,stu: Student3) {
            self.name = name
            self.banzhang = stu
        }
        deinit {
            print("(name) teacher deinit")
        }
    }

    //如果两个类中,其属性都是非可空类型,并且互相引用

    //那么会导致这两个对象永远不能创建出来

    var s3: Student3? = Student3(name: "xxx", teacherName: "zhuzhu")

    var t3 = Teacher3(name: "zhuzhu", stu: s3!)

    s3?.t = nil

    s3 = nil

    
    
    循环引用在闭包中的体现
    class ClosureClass {
        var name = "asdf"
        //利用方括号语法(捕获列表)来处理循环引用
        //多个之间用逗号分隔
        lazy var myClosure:Void->Int = {
            //[unowned self] //直接修饰unowned或weak
            [unowned this = self]//除了修饰以外,还可以取别名
            //[unowned this = self,unowned self]
            ()-> Int in
            print(this.name)
            print(self.name)
            return 5
        }
        deinit {
            print("closer deinit")
        }
    }
    //有两个对象,一个是ClosureClass对象,一个是闭包对象
    var cc: ClosureClass? = ClosureClass()
    cc?.myClosure()
    cc = nil
    cc?.myClosure()  //输出nil,说明已被销毁
  • 相关阅读:
    css样式预处理器
    cookie&localStorage&sessionStorage
    《程序员面试金典》---读书笔记
    《Linux多线程服务端编程--使用muduo C++ 网络库》---读书笔记
    慢慢走上正轨
    padding 和 margin 不为人知的一面 ---(深度整理)
    html+css代码需要注意的地方(整理)
    前言
    MikTex 和 TexStudio 输入中文日文
    .htaccess 二级域名绑定子目录
  • 原文地址:https://www.cnblogs.com/kangniuniu/p/4979037.html
Copyright © 2011-2022 走看看