對象回收時Weak指針自動被置為nil的實現(xiàn)原理

1. 前言

我們都知道Weak指針不會增加所引用對象的計數(shù),并在引用對象被回收的時候自動被置為nil曲稼。通常用于解決循環(huán)引用問題索绪。那么,自動被置為nil內(nèi)部是如何實現(xiàn)的呢贫悄?

2. 內(nèi)部實現(xiàn) — Weak表

Runtime維護了一個Weak表瑞驱,用于存儲指向某個對象的所有Weak指針。Weak表其實是一個哈希表窄坦,Key是所指對象的地址唤反,Value是Weak指針的地址(這個地址的值是所指對象的地址)的數(shù)組。

在對象被回收的時候鸭津,經(jīng)過層層調(diào)用彤侍,會最終觸發(fā)下面的方法將所有Weak指針的值設(shè)為nil。(具體定義在objc-weak.m中)

PRIVATE_EXTERN void 
arr_clear_deallocating(weak_table_t *weak_table, id referent) {
    {
        weak_entry_t *entry = weak_entry_for_referent(weak_table, referent);
        if (entry == NULL) {
            /// XXX shouldn't happen, but does with mismatched CF/objc
            //printf("XXX no entry for clear deallocating %p\n", referent);
            return;
        }
        // zero out references
        for (int i = 0; i < entry->referrers.num_allocated; ++i) {
            id *referrer = entry->referrers.refs[i].referrer;
            if (referrer) {
                if (*referrer == referent) {
                    *referrer = nil;
                }
                else if (*referrer) {
                    _objc_inform("__weak variable @ %p holds %p instead of %p\n", referrer, *referrer, referent);
                }
            }
        }
            
        weak_entry_remove_no_lock(weak_table, entry);
        weak_table->num_weak_refs--;
    }
}

簡單來說逆趋,這個方法首先根據(jù)對象地址獲取所以Weak指針地址的數(shù)組拥刻,然后遍歷這個數(shù)組把其中的數(shù)據(jù)設(shè)為nil,最后把這個entry從Weak表中刪除父泳。

這里只簡單說說對象回收時,Weak指針如何設(shè)為nil吴汪,至于Weak指針如何注冊到Weak表中惠窄、如何維護可以參考objc-weak.m中的其它源碼。從實現(xiàn)中可以看出漾橙,Weak指針的使用涉及到Hash表的增刪改查杆融,有一定的性能開銷。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末霜运,一起剝皮案震驚了整個濱河市脾歇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌淘捡,老刑警劉巖藕各,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異焦除,居然都是意外死亡激况,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乌逐,“玉大人竭讳,你說我怎么就攤上這事≌闾撸” “怎么了绢慢?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長洛波。 經(jīng)常有香客問我胰舆,道長,這世上最難降的妖魔是什么奋岁? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任思瘟,我火速辦了婚禮,結(jié)果婚禮上闻伶,老公的妹妹穿的比我還像新娘滨攻。我一直安慰自己,他們只是感情好蓝翰,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布光绕。 她就那樣靜靜地躺著,像睡著了一般畜份。 火紅的嫁衣襯著肌膚如雪诞帐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天爆雹,我揣著相機與錄音停蕉,去河邊找鬼。 笑死钙态,一個胖子當著我的面吹牛慧起,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播册倒,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蚓挤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了驻子?” 一聲冷哼從身側(cè)響起灿意,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎崇呵,沒想到半個月后缤剧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡域慷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年鞭执,在試婚紗的時候發(fā)現(xiàn)自己被綠了司顿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡兄纺,死狀恐怖大溜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情估脆,我是刑警寧澤钦奋,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站疙赠,受9級特大地震影響付材,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜圃阳,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一厌衔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捍岳,春花似錦富寿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至银萍,卻和暖如春变勇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贴唇。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工搀绣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人戳气。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓链患,卻偏偏與公主長得像,于是被迫代替她去往敵國和親物咳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容