Swift學(xué)習(xí)筆記-自動(dòng)引用計(jì)數(shù)

引用計(jì)數(shù)應(yīng)用于類的實(shí)例。結(jié)構(gòu)體和枚舉類型是值類型,不是引用類型,也不是通過引用的方法存儲(chǔ)和傳遞。

弱引用

聲明屬性或者變量時(shí),在前面加上weak關(guān)鍵字表明這是一個(gè)弱引用。(當(dāng)arc設(shè)置弱引用為nil時(shí),屬性觀察不會(huì)被觸發(fā))

class Person {
    let name : String
    init(name:String) {
        self.name = name
    }
    
    var apartment : Apartment?
    
    deinit {
        print("\(name) is being delloc")
    }
}

class Apartment {
    let name : String
    init(name:String) {
        self.name = name
    }
    
    weak var person : Person?
    
    deinit {
        print("\(name) is being empty")
    }
}

        var building : Apartment?
        var person : Person?
        building = Apartment(name: "愛情公寓")
        person = Person(name: "美嘉")
        building!.person = person
        person!.apartment = building
        
        person = nil

無主引用

和弱引用不同的是,無主引用在其他實(shí)例有相同或者更長(zhǎng)的生命周期時(shí)使用。在關(guān)鍵字前添加 unowned表示。

重要
使用無主引用,你必須確保引用始終指向一個(gè)未銷毀的實(shí)例。
如果你試圖在實(shí)例被銷毀后訪問該實(shí)例的無主引用,會(huì)觸發(fā)運(yùn)行時(shí)錯(cuò)誤。

class Customer {
    let name : String
    
    var card : CreditCard?
    
    init(name:String) {
        self.name = name
    }
    
    deinit {
        print("Custimer delloc")
    }
}

class CreditCard {
    let name : String
    
    unowned var customer : Customer
    
    init(name:String,cutomer:Customer) {
        self.name = name
        self.customer = cutomer
    }
    
    deinit {
        print("CreditCard delloc")
    }
}
        var john : Customer?
        john = Customer(name: "John")
        john?.card = CreditCard(name: "card", cutomer: john!)
        john = nil

Person和Apartment的例子展示了二個(gè)屬性的值都允許為nil,這種場(chǎng)景適合用弱引用來解決。
Customer和CreditCard的例子展示了一個(gè)屬性的值不允許為nil,這種場(chǎng)景適合用無主引用解決。

當(dāng)兩個(gè)屬性均可不為nil且互相引用時(shí),如下

class Country {
    let name : String
    var city : City!
    init(name:String,cityName:String) {
        self.name = name
        self.city = City(name:cityName,country:self)
    }
}

class City {
    let name : String
    unowned let country : Country
    
    init(name:String,country:Country) {
        self.name = name
        self.country = country
    }
}

解決閉包引起的循環(huán)引用

以下是造成了循環(huán)引用的代碼。

class HTMLElement {
    let name : String
    let text : String?
    
    lazy var asHTML : () -> String = {
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        }else{
            return "<\(self.name) />"
        }
    }
    
    init(name:String,text:String?=nil) {
        self.name = name
        self.text = text
    }
    
    deinit {
        print("銷毀")
    }
    
}

解決方法:聲明每個(gè)引用為弱引用或者無主引用。

注意
swift有以下要求:只要在閉包內(nèi)使用self成員,就要用self.name,self.someMethod(),而不是name,someMethod()。

使用無主引用:在閉包和捕獲的實(shí)例總是互相引用并且總是同時(shí)銷毀時(shí),將閉包內(nèi)的捕獲定義為無主引用。
弱引用:在被捕獲的引用可能會(huì)變?yōu)閚il時(shí),將閉包內(nèi)捕獲的定義為弱引用。
如果被捕獲的引用絕對(duì)不會(huì)變?yōu)閚il,應(yīng)該用無主引用。

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

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

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