swift----內(nèi)存管理

內(nèi)存管理不管是在ObjectC 還是swift上,在開發(fā)過程中都是我們需要關(guān)注的一個重點。剛好學(xué)習(xí)到,做此筆記

1.類的初始化和類的銷毀

1.類初始化使用init關(guān)鍵字;
2.類的銷毀使用deinit關(guān)鍵字。

eg:

class Student{
    let name : String
    var website = "JournalDev"
    //初始化
    init(name:String){
        self.name = name
        print("\(name) is being initialized")
    }
    //釋放變量:自動釋放,不能手動調(diào)用。
    deinit {
        print("\(name) is being deinitialized")
        print("\(website) is being deinitialized")
    }
}

var s : Student? = Student(name:"Chloe")
//打印結(jié)果:Chloe is being initialized
var reference = s//此時reference引用了s
var reference2 = reference//reference2引用了reference

//因為類是引用類型,此時,s被reference引用;reference被reference2引用;
reference = nil//reference is nil;沒有走deinit方法
s = nil//s is nil;沒有走deinit方法
reference2 = nil//走deinit方法

//打印結(jié)果:
//Chloe is being deinitialized
//JournalDev is being deinitialized
//從上面的例子可以看出,只有對類的引用全部無效時,類才被釋放。

2.循環(huán)引用(強引用)

因為類是引用類型,所以很容易造成循環(huán)引用,導(dǎo)致類不能被釋放;
eg:

class Major {
    let name : String
    var university : University?//引用了University類
    init(name : String) {
        self.name = name
    }
    deinit {
        print("\(name) is being deinitialized")
    }
}

class University{
    let uniName : String
    init(uniName : String) {
        self.uniName = uniName
    }
    var major : Major?//引用了Major類
    deinit {
        print("University \(uniName) is being deinitialized")
    }
}
//Major類和University此時是循環(huán)引用狀態(tài)?,F(xiàn)在我們對兩個類進(jìn)行初始化
var meMajor: Major?
var uni: University?

meMajor = Major(name: "John Doe")
uni = University(uniName: "IIT")

meMajor?.university = uni
uni?.student = meMajor

meMajor = nil
uni = nil

當(dāng)我們給meMajor和uni都置為nil時,此時發(fā)現(xiàn)Major和University都沒有被釋放;然后我們看一下怎么解決。

先了解一下引用類型:

引用類型有三種:strong、weak、unowned reference;
(1)strong:強引用是默認(rèn)情況下創(chuàng)建的引用的標(biāo)準(zhǔn)類型。
(2)weak:弱引用允許創(chuàng)建實例,但不計入弧的引用計數(shù)。通常,當(dāng)一個引用的生存期比另一個引用短時,應(yīng)該將其標(biāo)記為弱引用。弱引用可以為nil。
(3)unowned references:無主引用與弱引用類似,只是它們用于比其他引用具有更長生存期的引用。只有在絕對確定引用確實存在時才應(yīng)該使用無主引用,否則如果在nil引用上調(diào)用它,它將崩潰。也就是無主引用不可以置為nil。

解決辦法:所以上面的循環(huán)引用,我們可以用弱引用或者無主引用來解決循環(huán)引用問題。只要在屬性前面添加weak關(guān)鍵字就可以
class Major {
    let name : String
    weak var university : University?
    init(name : String) {
        self.name = name
    }
    deinit {
        print("\(name) is being deinitialized")
    }
}

class University{
    let uniName : String
    init(uniName : String) {
        self.uniName = uniName
    }
    weak var major : Major?
    deinit {
        print("University \(uniName) is being deinitialized")
    }
}
var meMajor: Major?
var uni: University?

meMajor = Major(name: "John Doe")
uni = University(uniName: "IIT")

meMajor?.university = uni
uni?.major = meMajor

meMajor = nil
uni = nil
//打印結(jié)果:
//University IIT is being deinitialized
//John Doe is being deinitialized

3.閉包循環(huán)引用

使用捕獲列表解析閉包中的引用循環(huán);閉包是引用類型,所以也會造成循環(huán)引用。
閉包中使用了[unowned self]和[weak self]都不會造成閉包循環(huán)引用問題。

class User {
    
    let name: String
    let skill: String
    //會造成循環(huán)引用
//    lazy var summary: () -> String = {
//        return "\(self.name) (\(self.skill))"
//    }
    
    //不會造成循環(huán)引用
//    lazy var summary: () -> String = {[unowned self] in
//        return "\(self.name) (\(self.skill))"
//    }
    //也不會造成循環(huán)引用
    lazy var summary:() -> String = {[weak self] in
        guard let weakSelf = self else { return }
        return "\(weakSelf.name) (\(weakSelf.skill))"
    }
    
    init(name: String, skill: String) {
        self.name = name
        self.skill = skill
    }
    
    deinit {
        print("Deallocated User")
    }
    
}

var name: User? = User(name: "Anupam", skill: "Swift")

name?.summary()

name = nil
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容