swift進階七:引用計數(Strong、Unowned、Weak)

swift進階 學習大綱

上一節,介紹了方法調度 & @objc & 指針。本節,我們就探究較難的引用計數,將從以下4個方面探索:

  1. Swift三大引用計數(strong、unowned、weak)
  2. 強引用 & 無主引用
  3. CFGetRetainCount計數統計
  4. 弱引用

swift中的引用計數OC一致,都是采用ARC(自動引用計數)管理。

OC的對象都是以objc_object為模板創建,其中首元素isa

  • 開啟指針優化(nonpointer): 在isa存儲引用計數,可使用散列表進行拓展存儲
  • 未開啟指針優化: 直接使用散列表進行存儲
  • swift引用計數:
  • swift對象都是以HeapObject為模板創建,其中HeapObject的模板中第二個元素,是refCount引用計數屬性,該屬性記錄了strong(強引用計數)和unowned(弱引用計數)等信息。
  • weak修飾對象,會另外生成WeakReference對象,內部HeapObjectSideTableEntry散列表類在原heapObject類的基礎上,重新記錄了refCount(管理strongunowned引用計數)并新增了weakBits弱引用計數。

1. Swift三大引用計數(strong、unowned、weak)

首先,我們先通過案例,體驗一下Swift對象的三種引用類型:

  • strong(默認強引用類型)、unowned(無主引用類型)、weak(弱引用類型)
image.png
  1. 不管是哪種引用持有的都是原對象(從p到p5內存地址可以看出)
  2. 在每一行執行完后,x/4g打印p對象內存信息,在第二地址上,可以清晰感受到,強引用無主引用引用計數有規律增加,而弱引用沒有變化
  • 經過了上面的初體驗,我們對強引用無主引用計數的位置有了初步的感受,但弱引用的信息存放不明朗
  • 下面,我們通過案例SIL中間代碼Swift源碼匯編等方式,一點點揭開他們的面紗??

2. 強引用 & 無主引用

2.1 源碼探索

  • 當前以默認initialized方式進行初始化,分析HeapObject對象引用計數
  • swift源碼探索過程:
    image.png
  • refCount內存布局
    image.png
  • 現在,我們知道強引用無主引用是在Uint64_t 8位refCount的不同位置。

2.2 引用計數分析

下面通過案例檢查一下:

  • 創建一個Swift命令行項目
class HTPerson {
    var age  = 10
    var name = "ht"
}

var t = HTPerson()
var t1 = t
var t2 = t
print("end")
  • 【嘗試一】: 在t1處斷點t對象強引用無主引用計數都為1
image.png
  • 【嘗試二】: 在t2處斷點t對象強引用計數2無主引用計數1
image.png

2.3 強引用計數+1

  • 還是以上面測試代碼為例,我們結合SIL中間代碼和Swift源碼分析:

【情況一】僅創建對象,默認強引用計數1

image.png

【情況二】進行一次引用強引用計數2SIL中可以看到copy_addr匯編可以看到使用swift_retain,在swift源碼中可以知道執行路徑為:

swift_retain->refCounts.increment(1)->incrementStrongExtraRefCount->強引用計數+1

image.png

3. CFGetRetainCount計數統計

  • CFGetRetainCount會在執行前,對對象進行strong_retain操作,在執行后,完成release_value操作。
    所以swiftCFGetRetainCount打印的強引用計數比原引用計數多1

注意:swift中,在lldbp打印內存,會引用計數+1,影響影響CFGetRetainCount結果
(斷點,p打印一次或多次,x/4g在內存信息中可看到引用計數明顯變化)

【情況一】不打印,無retain和release

image.png

【情況二】打印一次CFGetRetainCount,執行前strong_retain +1,執行完release_value -1

image.png

4. 弱引用

  • 我們知道swift是使用ARC(自動引用計數管理)的。如果產生循環引用,我們必須有弱引用機制去打破循環

swift中的弱引用,使用weak修飾。與OC不同的是:

  • OC:
    弱引用計數是存放在全局維護散列表中,isa中會記錄是否使用了散列表
    引用計數0時,自動觸發dealloc,會檢查清空當前對象散列表計數

  • swift:
    弱引用計數也是存放在散列表中,但這個散列表不是全局的。

    • 如果對象沒有使用weak弱引用,就是單純的HeapObject對象,沒有散列表
    • 如果使用weak弱引用,會變為WeakReference對象。這是一個Optionl(可空對象)。其結構中自帶散列表計數區域。
      swift散列表refCount無關聯。當強引用計數0時,不會觸發散列表的清空。而是在下次訪問發現當前對象不存在(為nil)時,會清空散列表計數

下面,我們通過案例源碼來分析swift弱引用WeakReference對象內存結構

案例:

  • 可以發現:
    weak修飾前,p對象是HeapObject類型,可從refCount中看出強引用計數無主引用計數
    weak修飾后,p對象的類型變了

    image.png

  • 可以看到weak修飾p1對象,變成了optinal可選值
    (不難理解,weak修飾對象改變原對象的引用計數,只是一層可空狀態

    image.png

  • 斷點匯編可以看到swift_weakInit初始化,swift_weakDestroy釋放。

    image.png

  • 進入swift源碼,搜索swift_weakInit

image.png
  • 常規對象弱引用對象區別:
image.png
  • 現在,我們已知道弱引用實際上是WeakReference對象,信息都存儲在side弱引用表中,可仿照getSideTable函數左移3位得到side散列表地址。讀取弱引用信息

我們回到上面案例

image.png

  • 了解結構后,關于弱引用引用計數+1-1釋放都在WeakReference類中有介紹,可以自行了解。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容