前言
????????在WWDC20中,蘋果官方介紹了對(duì)類的修改,其中出現(xiàn)了一個(gè)新的結(jié)構(gòu)?class_rw_ext_t必逆,那么為什么會(huì)出現(xiàn)這個(gè)東東呢?在看這篇文章時(shí)揽乱,希望你是閱讀過runtime源碼的末患。
Why?
? ? ? ? 首先锤窑,我們先來了解下璧针,clean memory 與 dirty memory的區(qū)別:
? ? ? ? clean memory : 加載后,不會(huì)被修改渊啰。在內(nèi)存緊張時(shí)探橱,可以從內(nèi)存中移除,需要時(shí)再次從文件中加載绘证。
? ? ? ? dirty memory : 加載后隧膏,會(huì)被修改,一直存在于內(nèi)存中嚷那,所以dirty memory更加”寶貴“
????????在舊版本的runtime中胞枕,類一旦被加載到內(nèi)存中,就會(huì)初始化一個(gè)rw結(jié)構(gòu)魏宽,并將所有的ro中的methods,protocols,properties復(fù)制到rw中腐泻,rw屬于dirty memory决乎。但大約90%的類并不需要對(duì)rw中的methods等進(jìn)行修改,所以這部分”dirty memory“無疑是浪費(fèi)的派桩。所以蘋果對(duì)class_rw_t進(jìn)行進(jìn)一步拆分出class_rw_ext_t用來存儲(chǔ)這部分可能被修改的methods等构诚,而?class_rw_ext_t只有在需要的時(shí)候,才被創(chuàng)建铆惑。而不被創(chuàng)建的class_rw_ext_t則是優(yōu)化后范嘱,相對(duì)于舊版runtime可以節(jié)省下的內(nèi)存空間。
How员魏?
? ? ? ? 以“查找方法”為例丑蛤,對(duì)新舊版本runtime進(jìn)行比較:
? ? ? ? 舊版本runtim直接訪問rw的methods屬性,查找方法撕阎。在類加載到內(nèi)存時(shí)盏阶,直接copy了ro的方法列表,所以無論方法列表是否被改變闻书,這塊內(nèi)存都會(huì)開辟名斟。
? ? ? ? 新版runtime則是訪問rw的methods()成員方法來獲取類的方法列表,而且在methods方法中判斷了魄眉,rw_ext_t是否已經(jīng)初始化了砰盐,如果初始化,則讀取class_rw_ext_t的methods,否則從ro的baseMethods()獲取類的方法列表坑律⊙沂幔看下面的代碼:
????????總結(jié):新版的rumtime利用了懶加載的機(jī)制,在類的methods晃择,properties等需要修改時(shí)冀值,才初始化class_rw_ext_t這塊“dirty+memory”存儲(chǔ)這些列表,這樣就減少了在舊版rumtime中90%的類在rw中直接復(fù)制ro中數(shù)據(jù)浪費(fèi)的內(nèi)存宫屠。
補(bǔ)充:那class_rw_ext_t內(nèi)存又是在何時(shí)開辟的呢列疗?
????????1.裝載分類時(shí)
????????2.runtime動(dòng)態(tài)添加方法時(shí)
????????3.runtime添加property時(shí)
????????4.runtime添加protocol時(shí)