天天看點

三十二 Swift5.0之 記憶體相關

/*
Swift記憶體管理:
管理引用類型的記憶體, 不會管理值類型, 值類型不需要管理
記憶體管理原則: 當沒有任何強引用指向對象, 系統會自動銷毀對象
(預設情況下所有的引用都是強引用)
如果做到該原則: ARC
*/

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


/*
weak弱引用
*/

class Person2 {
    var name:String
    init(name:String){
        self.name = name
    }
    deinit{
        print("deinit")
    }
}
// 強引用, 引用計數+1
var strongP = Person2(name: "gezi") // 1
var strongP2 = strongP // 2

// 弱引用, 引用計數不變
// 如果利用weak修飾變量, 當對象釋放後會自動将變量設定為nil
// 是以利用weak修飾的變量必定是一個可選類型, 因為隻有可選類型才能設定為nil
weak var weakP:Person2? = Person2(name: "gezi")
if let p = weakP{
    print(p)
}else
{
    print(weakP as Any)
}


/*
unowned無主引用 , 相當于OC unsafe_unretained
unowned和weak的差別:
1.利用unowned修飾的變量, 對象釋放後不會設定為nil. 不安全
  利用weak修飾的變量, 對象釋放後會設定為nil
2.利用unowned修飾的變量, 不是可選類型
  利用weak修飾的變量, 是可選類型
什麼時候使用weak?
什麼時候使用unowned?
*/

class Person3 {
    var name:String
    init(name:String){
        self.name = name
    }
    deinit{
        print("deinit")
    }
}
unowned var weakP3:Person3 = Person3(name: "gezi")




/*
循環引用
ARC不是萬能的, 它可以很好的解決記憶體問題, 但是在某些場合不能很好的解決記憶體洩露問題
例如兩個或多個對象之間的循環引用問題
*/

class Person4 {
    let name:String // 姓名
    // 人不一定有較高價的電梯大廈
    weak var apartment: Apartment? // 較高價的電梯大廈
    init(name:String){
        self.name = name
    }
    deinit{
        print("\(self.name) deinit")
    }
}
class Apartment {
    let number: Int // 房間号
    var tenant: Person4? // 租客
    init(number:Int){
        self.number = number
    }
    deinit{
        print("\(self.number) deinit")
    }
}
var p4:Person4? = Person4(name: "gezi")
var a4:Apartment? = Apartment(number:888)

p4!.apartment = a4 // 人有一套較高價的電梯大廈
a4!.tenant = p4! // 較高價的電梯大廈中住着一個人

// 兩個對象沒有被銷毀, 但是我們沒有辦法通路他們了. 記憶體洩露
p4 = nil
a4 = nil



class Person5 {
    let name:String // 姓名
    // 人不一定有信用卡
    var card: CreditCard?
    init(name:String){
        self.name = name
    }
    deinit{
        print("\(self.name) deinit")
    }
}
class CreditCard{
    let number: Int
    // 信用卡必須有所屬使用者
    // 當某一個變量/常量必須有值, 一直有值, 那麼可以使用unowned修飾
    unowned let person: Person5
    init(number:Int, person: Person5){
        self.number = number
        self.person = person
    }
    deinit{
        print("\(self.number) deinit")
    }
}
var p5:Person5? = Person5(name: "gezi")
var cc:CreditCard? = CreditCard(number: 8888888, person: p5!)
p5 = nil
cc = nil


           

繼續閱讀