Swift 基础学习(内存管理)

/*
    Swift 内存管理
*/

/*
(1)析构方法
对象的内存被回收前夕被隐式调用的方法.主要执行一些额外的操
作.
比如: 关闭文件,断开网络,释放对象特有的一些资源等.
dealloc, MRC [obj release]
ARC, 弱化内存操作(Swift的析构方法,不用去管理内存).
*/
class FileHandle {
    var fd: Int32? //文件描述符
    init(path: String) {
        let ret = open(path, O_RDONLY)
        if (ret == -1) {
            fd = nil
        }else {
            fd = ret
        }
    }
    deinit {
        if let ofd = fd {

            close(ofd)
        }
        print("对象被销毁,持有资源被释放")
    }
}
//对象 (引用类型)何时被销毁,对象没有任何引用的时候.
var ofh: FileHandle? = FileHandle(path: "/etc/passwd")
//目前没有任何的引用指向刚刚构造的对象.
//当注释掉,该对象没有被销毁,所以就不会走deinit析构方法
//ofh = nil

/*
(2)析构方法的自动继承-父类的析构方法会被自动调用,不需要
子类管理
*/
class SomeClass {
    deinit {
        print("SomeClass deinit!")
    }
}
class SubOfClass: SomeClass {
    deinit {
        print("SubOfClass deinit!")
    }
}
var osub: SubOfClass? = SubOfClass()
osub = nil

/*
(3)Swift语言的内存管理分析
*内存管理的对象-引用类型的对象(class类型)
*内存管理的原则:当没有任何引用指向某个对象的时候,系统会自
动销毁该对象.
*如何做到该原则:通过ARC技术
*/
class MenArc {
    deinit {
        print("deinit!")
    }
}
var t0 = MenArc()
var t1 = t0
var t2 = MenArc()
//t0,t1跟t2指向同一个对象
t0 = t2
t1 = t2

/*
(4)weak引用(弱引用)
*/
class Ref {
    deinit {
        print("Ref deinit!")
    }
    func test() {
        print("Test!")
    }
}
//强引用,默认得引用方式
var strongRef = Ref()//引用计数为1
var strong1Ref1 = strongRef//引用计数为2
//弱引用,weak引用非常安全得引用方式.
weak var weakRef = Ref() //ARC
//当去掉weak修饰时,并不会调用deinit析构方法
// var weakRef = Ref() //ARC
//弱引用,是一个可选类型.

weak var weakRef1: Ref? = Ref()
//不能通过强制解析进行访问,编译会通过,运行会崩溃
//weakRef1!.test()
//当引用时,需要判断其是否为nil
if let wr = weakRef1 {
    wr.test()
}

/*
(5)unowned引用(弱引用),不是可选类型
*/

/*
(6)循环强引用
ARC不是万能的,它可以很好的解决内存过早释放的问题,但是在
某些场合下不能很好的解决内存泄露的问题.
*/
class Person {
    let name: String
    init(name: String) {
       self.name = name
    }
    var apartmet: Apartment?
    deinit {
        print("\(name) is being deinitialized")
    }
}
class Apartment {
    let number: Int
    init(number: Int) {
        self.number = number
    }
    weak var tenant: Person?
    deinit {
        print("Apartment #\(number) is being deinitialized")
    }
}
var john: Person?
var number73: Apartment?
john = Person(name: "john Appleseed")
number73 = Apartment(number: 73)

john!.apartmet = number73
number73!.tenant = john

//两个对象没有被销毁,但是我们没有办法再访问它们了,内存泄露
//解决办法:将某一个属性设置为弱引用即可weak, 在var tenant前面添加关键字weak
john = nil
number73 = nil

/*
(7)unowned解决循环强引用
*/
class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) {
        self.name = name
    }
    deinit {
        print("\(name) is being deinitialized")
    }
}
class CreditCard {
    let number: UInt64
    //解决循环引用
    unowned let customer: Customer
    init(number: UInt64, customer: Customer){
        self.number = number
        self.customer = customer
    }
    deinit{
        print("Card #\(number) is being deinitalized")
    }
}
var john1: Customer?
john1 = Customer(name: "John1 Appleseed")
john1!.card = CreditCard(number: 1245_5678_9012_3456, customer: john1!)
john1 = nil
(6)未用弱引用weak修饰前这4行代码对应以下图内容:
john = Person(name: "john Appleseed")
number73 = Apartment(number: 73)

john!.apartmet = number73
number73!.tenant = john

这里写图片描述

对应以下内容:
//导致内存泄露,john的apartment和number73的tenant两个对象还互相持有导致我们的内存泄露
john = nil
number73 = nil

这里写图片描述

通过将某个属性设置为弱引用weak时如图所示:
weak var tenant: Person?
john = Person(name: "john Appleseed")
number73 = Apartment(number: 73)

john!.apartmet = number73
number73!.tenant = john

这里写图片描述

对应以下图示:
john = nil
number73 = nil

这里写图片描述

这里写图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章