Objective-C 運行時的改進之?dāng)?shù)據(jù)結(jié)構(gòu)的變化

WWDC2020介紹Objective-C 運行時的改進,主要介紹了三個變化:

1.Class data structures changes;

首先是數(shù)據(jù)結(jié)構(gòu)的變化,Objective-C 運行時會使用他們來追蹤類。

2.Relative method lists;

Objective-C方法列表的變化

3.tagged pointer 格式的變化;

本文先對Class data structures changes展開講解:
在磁盤上彪薛,在你的app二進制文件中 類時這樣的:

Superclass.png

首先這個類對象本身,包含了最常被訪問的信息指向
元類(Metaclass)租副、超類(Superclass)方法緩存的指針(Method cache)栋操。
它還有一個指向更多數(shù)據(jù)的指針,存儲額外信息的地方叫做class_ro_t, ro代表只讀茬高,它包括像類名稱,方法假抄、協(xié)議和實例變量的信息怎栽。
class_ro_t.png

Swift 類和Objective-C類共享這一基礎(chǔ)結(jié)構(gòu),所以每個Swift類也有這些數(shù)據(jù)結(jié)構(gòu)宿饱,當(dāng)類第一次從磁盤加載到內(nèi)存中時婚瓜,他們一開始也是這樣的,但是一經(jīng)使用刑棵,他們就會發(fā)生變化巴刻。
這里先區(qū)分下:clean memorydirty memory

clean memory:是指加載后不會發(fā)生更改的內(nèi)存。class_ro_t 就屬于clean memory因為它是屬于只讀的蛉签。

dirty memory:是指在進程運行時會發(fā)生更改的內(nèi)存胡陪。
類結(jié)構(gòu)一經(jīng)使用就會變成dirty memory,因為運行時會向它寫入新的數(shù)據(jù)碍舍。
例如:創(chuàng)建一個新的方法緩存并從類中指向它柠座,dirty memoryclean memory要昂貴得多,只要進程在運行片橡,它就一直存在妈经。
另一方面clean memory 可以進行移除從而節(jié)省更多的內(nèi)存空間,因為如果你需要clean memory系統(tǒng)可以從磁盤中重新加載捧书,MacOS 可以選擇換出dirty memory,但是因為iOS不使用swap吹泡,所以dirty memory在iOS中代價很大,dirty memory是這個類數(shù)據(jù)被分成兩部分的原因经瓷,可以保持清潔的數(shù)據(jù)越多越好爆哑,通過分離那些永遠不會更改的數(shù)據(jù),可以把大部分的類數(shù)據(jù)存儲為clean memory舆吮。

這些數(shù)據(jù)足以讓我們開始揭朝,但是運行時需要追蹤每個類的更多信息队贱,所以當(dāng)一個類首次被使用,運行時會為它分配額外的存儲容量潭袱,這個運行時分配的存儲容量是class_rw_t 用于讀取-編寫數(shù)據(jù)柱嫌,在這個數(shù)據(jù)結(jié)構(gòu)中,我們存儲了只有在運行時才會生成的新信息屯换。

class_rw_t.png

例如:所有的類都會鏈接成一個樹狀結(jié)構(gòu)编丘,這是通過使用First SubclassNext sibling Class 指針實現(xiàn)的,這運行時遍歷當(dāng)前使用的所有類趟径,對于使方法緩存無效非常有用瘪吏。

class_rw_t.png

但為什么方法和屬性也在只讀數(shù)據(jù)中時這里還有方法和屬性呢癣防?
因為它們可以在運行時進行更改蜗巧。
當(dāng)category被加載時它可以向類中添加新的方法,而且開發(fā)者可以使用運行時API動態(tài)地添加他們蕾盯,因為class_ro_t是只讀的幕屹,所以我們需要在class_rw_t中追蹤這些東西。

class_rw_t.png

現(xiàn)在這樣做會占用相當(dāng)多的內(nèi)存级遭,在任何給定的設(shè)備中都有許多類在使用望拖。我們在iPhone上的整個系統(tǒng)中測量了,大約30兆字節(jié)這些class_rw_t結(jié)構(gòu)挫鸽,那么如何縮小這些數(shù)據(jù)結(jié)構(gòu)呢说敏?

在讀取-編寫部分需要這些東西,因為他們可以喜愛運行時進行更改丢郊,但是通過檢查實際設(shè)備上的使用情況盔沫,我們發(fā)現(xiàn)大約只有10%的類真正地更改了他們的方法,只有Swift類會使用這個demangled name字段,但是Swift類并不需要這一字段枫匾,除非有東西詢問它們的 Objective-C名稱時才需要
class_rw_t.png

所以架诞,我們可以拆掉那些平時不用的部分,這將class_rw_t的大小減少了一半
class_rw_t.png

對于確實需要額外信息的類干茉,我們可以分配這些擴展記錄中的一個谴忧,并把它滑到類中供其使用。


class_rw_t.png

大約90%的類從不需要這些擴展數(shù)據(jù)角虫,這在系統(tǒng)范圍內(nèi)可以節(jié)約大約14MB的內(nèi)存沾谓,這些內(nèi)存現(xiàn)在可以用于更有效的用途,比如存儲你的APP的數(shù)據(jù)戳鹅,因此 實際上你可以在你的Mac上看到這一變化帶來的影響搏屑,這只需要在終端機上運行一些簡單的命令,現(xiàn)在一起來看一下粉楚。
在此進入Macbook的終端辣恋,要運行一個命令它在任何Mac上都可用叫做heap,它還允許你檢查正在運行的進程所使用的堆內(nèi)存亮垫,將在Mac中的Mail app上運行它 ,現(xiàn)在 如果我運行該命令伟骨,他會輸出千行饮潦,顯示通過郵件進行的每個堆分配,所以 我只是要 grep 它為 我們今天一直在談?wù)摰念愋?class_rw_t類型 我還需要查詢標(biāo)頭 從返回的結(jié)果中,

heap Mail.png

可以看到 在郵件app中使用了大約9000個這樣的class_rw_t類型哨查,但是其中大約十分之一 900 多一點實際上需要使用這一擴展信息溺健,所以可以很容易地計算出通過這個改變所有節(jié)省的內(nèi)存,這是大小減半的類型稀并,所以如果我們從這個數(shù)字中減去,必須分配給擴展類型的內(nèi)存量单默,可以看到節(jié)省了大約1兆字節(jié)數(shù)據(jù)的四分之一碘举。

如果在系統(tǒng)范圍內(nèi)進行擴展,對dirty memory而言 這是真正的節(jié)省內(nèi)存搁廓。

現(xiàn)在很多從類獲取數(shù)據(jù)的代碼引颈,必須同時處理那些有擴展數(shù)據(jù)和沒有擴展數(shù)據(jù)的類,運行時會為你處理這一切境蜕,并且從外部看 一切都像往常一樣工作蝙场,只是使用了更少內(nèi)存,之所以會這樣粱年,是因為讀取這些結(jié)構(gòu)的代碼售滤,都在運行時內(nèi)并且還會同時進行更新.
class_rw_t.png

堅持使用這些API真的很重要
因為試圖直接訪問這些數(shù)據(jù)的結(jié)構(gòu)的代碼,都將在今年的OS版本中停止工作台诗,舊東西已經(jīng)發(fā)生了變化完箩,而且該代碼不知道新的布局,看到一些真實的代碼由于這些變化而崩潰拉庶,除了你自己的代碼之外嗜憔,還要注意哪些外部依賴性,可能正把他們帶入到你的APP中氏仗,他們可能會在你沒有意識的情況下挖掘這些數(shù)據(jù)結(jié)構(gòu)吉捶,

class_rw_t.png

這些結(jié)構(gòu)中的所有信息都可以通過官方API獲取,有一些函數(shù) 如class_getName和class_getSuperclass當(dāng)你使用這些API訪問信息時,你知道 無論我們在后臺進行什么更改皆尔,他們都將繼續(xù)工作呐舔,所有的API都可以在Objective-C運行時說明文檔中找到。

以上就是WWDC2020介紹Objective-C 運行時的改進之?dāng)?shù)據(jù)結(jié)構(gòu)的變化的一些記錄慷蠕,希望對大家的學(xué)習(xí)有所幫助珊拼。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市流炕,隨后出現(xiàn)的幾起案子澎现,更是在濱河造成了極大的恐慌仅胞,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剑辫,死亡現(xiàn)場離奇詭異干旧,居然都是意外死亡,警方通過查閱死者的電腦和手機妹蔽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門椎眯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人胳岂,你說我怎么就攤上這事编整。” “怎么了乳丰?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵掌测,是天一觀的道長。 經(jīng)常有香客問我成艘,道長赏半,這世上最難降的妖魔是什么贺归? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任淆两,我火速辦了婚禮,結(jié)果婚禮上拂酣,老公的妹妹穿的比我還像新娘秋冰。我一直安慰自己,他們只是感情好婶熬,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布剑勾。 她就那樣靜靜地躺著,像睡著了一般赵颅。 火紅的嫁衣襯著肌膚如雪虽另。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天饺谬,我揣著相機與錄音捂刺,去河邊找鬼。 笑死募寨,一個胖子當(dāng)著我的面吹牛族展,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拔鹰,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼仪缸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了列肢?” 一聲冷哼從身側(cè)響起恰画,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤宾茂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拴还,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刻炒,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年自沧,在試婚紗的時候發(fā)現(xiàn)自己被綠了坟奥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡拇厢,死狀恐怖爱谁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情孝偎,我是刑警寧澤访敌,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站衣盾,受9級特大地震影響寺旺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜势决,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一阻塑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧果复,春花似錦陈莽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至迈窟,卻和暖如春私植,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背车酣。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工曲稼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骇径。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓躯肌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親破衔。 傳聞我的和親對象是個殘疾皇子清女,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

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