Side Table
的引入是Swift
弱引用管理系統(tǒng)中的一個(gè)明智改進(jìn)轧飞,它最早出現(xiàn)在Swift 4
中萎羔。
讓我們仔細(xì)研究一下Side Table
的概念以及它解決了哪些問(wèn)題涂炎。
Swift引用計(jì)數(shù) - 核心概念
- 強(qiáng)引用對(duì)象會(huì)持有這個(gè)實(shí)例,并且只要強(qiáng)引用仍然存在焕议,就不允許對(duì)其進(jìn)行釋放柳弄。
- 弱引用是一種引用窜护,它不會(huì)持有所引用的實(shí)例,因此也不會(huì)阻止ARC銷(xiāo)毀所引用的實(shí)例买羞。
-
Unowned
引用方式也是弱引用的一種袁勺。 區(qū)別是訪問(wèn)計(jì)數(shù)器為零的引用會(huì)導(dǎo)致運(yùn)行時(shí)錯(cuò)誤雹食。 當(dāng)另一個(gè)實(shí)例的壽命相同或更長(zhǎng)時(shí)畜普,可以使用它。
同樣值得注意的是群叶,Swift中的對(duì)象有三種計(jì)數(shù)器:強(qiáng)引用吃挑,弱引用和無(wú)主引用。 這些計(jì)數(shù)器存儲(chǔ)在isa
之后或者存儲(chǔ)在Side table
中街立,稍后將對(duì)其進(jìn)行說(shuō)明舶衬。
除此之外,弱引用和無(wú)主引用的計(jì)數(shù)器比強(qiáng)引用多+1赎离。 當(dāng)對(duì)象執(zhí)行完析構(gòu)和銷(xiāo)毀內(nèi)存后逛犹,這個(gè)附加值將減小。 為了使本文簡(jiǎn)單,我將使用0作為兩種類(lèi)型引用的起點(diǎn)虽画。
Swift4之前的弱引用管理
為了演示舊引用計(jì)數(shù)的工作原理舞蔽,讓我們從一個(gè)示例入手。
class User {
let id: Int
let email: String
}
這是一個(gè)帶有兩個(gè)屬性的User
類(lèi)码撰。 下面的圖片表示對(duì)象在內(nèi)存中的表示渗柿。
類(lèi),屬性和引用計(jì)數(shù)器是內(nèi)聯(lián)存儲(chǔ)的脖岛。 它比將數(shù)據(jù)存儲(chǔ)在外部?jī)?nèi)存塊中要快一些朵栖。
假設(shè)有一個(gè)弱引用 引用了這個(gè)User,并且一段時(shí)間后柴梆,強(qiáng)計(jì)數(shù)器變?yōu)榱肆阍山Γ跤?jì)數(shù)器仍然不為零。
在這種情況下轩性,自動(dòng)引用計(jì)數(shù)將會(huì)把該對(duì)象從內(nèi)存
中刪除声登。 盡管這樣會(huì)導(dǎo)致對(duì)象銷(xiāo)毀,但不會(huì)釋放其內(nèi)存揣苏。
當(dāng)另一個(gè)對(duì)象通過(guò)弱引用訪問(wèn)被銷(xiāo)毀的對(duì)象時(shí)悯嗓,弱計(jì)數(shù)器將減少。 當(dāng)弱計(jì)數(shù)器達(dá)到零時(shí)卸察,將最終釋放內(nèi)存脯厨。 這意味著我們的User成為可能長(zhǎng)時(shí)間占用內(nèi)存的僵尸對(duì)象。
Swift 的 Side Table
Side Table
是一個(gè)單獨(dú)的內(nèi)存塊坑质,用于存儲(chǔ)對(duì)象的其他信息合武。 現(xiàn)在它只存儲(chǔ)了計(jì)數(shù)器和flags。
該對(duì)象最初是沒(méi)有Side Table
的涡扼,在以下情況下會(huì)自動(dòng)創(chuàng)建:
- 對(duì)象由弱引用指向時(shí)
-
strong
或unowned
計(jì)數(shù)器溢出(在32位系統(tǒng)上稼跳,嵌入式計(jì)數(shù)器很小)吃沪。
對(duì)象和Side Table
都具有指向彼此的指針汤善。 獲取Side Table
是一種單向操作。
另一件需要引起注意的事票彪,“弱”引用現(xiàn)在直接指向Side Table
红淡,而“強(qiáng)”和“無(wú)主”引用仍然直接指向?qū)ο蟆?這樣就可以完全釋放對(duì)象的內(nèi)存。
總結(jié)
Side Table
為原來(lái)的引用計(jì)數(shù)帶來(lái)了明顯的改進(jìn):
- 首先降铸,它允許弱引用指向的對(duì)象按時(shí)釋放而不會(huì)存在僵尸對(duì)象在旱。
- 其次,它可能會(huì)在將來(lái)的發(fā)行版中為擴(kuò)展其他存儲(chǔ)屬性打開(kāi)大門(mén)推掸。
推薦閱讀
- Apple Swift Book — Automatic Reference Counting https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html#ID52
- Swift Source Code — RefCount.h https://github.com/apple/swift/blob/d1c87f3c936c41418ee93320e42d523b3f51b6df/stdlib/public/SwiftShims/RefCount.h#L44
- 阿里大牛從源碼解析弱引用 https://juejin.im/post/5c7b835af265da2d881b4457
作者:Maxim Eremenko
翻譯:樂(lè)Coding