内存管理:内存泄漏和空悬指针

 

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

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

实例: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,说明已被销毁

 

posted @ 2015-11-23 21:02  爱学习~天天学习  阅读(361)  评论(0编辑  收藏  举报