iOS開發(fā)之 runtime(30) :none-lazy classes

logo

本系列博客是本人的源碼閱讀筆記影所,如果有 iOS 開發(fā)者在看 runtime 的,歡迎大家多多交流。

但大家心中的問題可能也接踵而至:

  • 方法 _getObjc2NonlazyClassList 作用是什么?
  • 什么是 remapped_class_map ?
  • 什么時(shí)候 創(chuàng)建 remapped_class_map 雨饺?以及什么時(shí)候 addRemappedClass ?

分析

對(duì)于第一個(gè)問題惑淳,相信大家稍微 Google 一下就會(huì)有結(jié)果:

NonlazyClass is all about a class implementing or not a +load method.
All the classes implemented in a given image file have a reference in a list stored in the "__DATA, __objc_classlist, regular, no_dead_strip" binary's section. This list allows the runtime system to keep track of all the classes stored in such file. However, not all of the classes need to be realized when the program starts up. That's why when a class implements a +load method, it also has a reference in a list stored in the "__DATA, __objc_nlclslist, regular, no_dead_strip" section.
So, _getObjc2NonlazyClassList retrieves the list of classes that do implement a +load method and are so called non-lazy. _getObjc2ClassList retrieves a list of all the classes in a image file, including the classes that don't have a +load method (and are called lazy) and the non-lazy ones. Non-lazy classes must be realized when the program starts up. Lazy classes, on the other hand, don't need to be realized immediately. This may be delayed until the class receives a message for the first time, for example (that's the reason for them to be considered "lazy").
The same is true for categories, by the way.

以上引用來自:Objective-C: What is a lazy class?

也就是說额港,如果一個(gè)類實(shí)現(xiàn)了 +load 方法,那么它就是個(gè) NonlazyClass汛聚。筆者為了證實(shí)這一點(diǎn)锹安,做了個(gè)驗(yàn)證:

// Realize non-lazy classes (for +load methods and static instances)
for (EACH_HEADER) {
    classref_t *classlist =
    _getObjc2NonlazyClassList(hi, &count);
    for (i = 0; i < count; i++) {
        Class cls = remapClass(classlist[i]);
//這里加了代碼用于測(cè)試
        if (0 == strcmp(cls->mangledName(), "TestObject")) {
                printf("TestObject is non-lazy Class\n");
                fflush(stdout);
        }
        if (!cls) continue;
        realizeClass(cls);
    }
}

其中,TestObject 的定義如下:

@implementation TestObject
+(void) load {
    
}

int MyWeakLinkedFunction () {
    return 1;
}
@end

那么,另外一個(gè)問題來了:
有多少 non-lazy class 叹哭?同樣的忍宋,筆者寫了如下代碼,打印出所有的 non-lazy class :

// Realize non-lazy classes (for +load methods and static instances)
for (EACH_HEADER) {
    classref_t *classlist =
    _getObjc2NonlazyClassList(hi, &count);
    for (i = 0; i < count; i++) {
        Class cls = remapClass(classlist[i]);
        //這里加了代碼用于測(cè)試
        printf("non-lazy Class:%s\n",cls->mangledName());
        fflush(stdout);
        if (!cls) continue;
        realizeClass(cls);
    }
}

打印的結(jié)果總結(jié)到筆者的GitHub了:non-lazy-classes.txt

可以看到风罩,大概有60個(gè) non-lazy-classes糠排。

什么時(shí)候創(chuàng)建 remapped_class_map ?

其實(shí)函數(shù)

static NXMapTable *remappedClasses(bool create)

已經(jīng)告訴我們了超升。
參數(shù) create 告訴是否需要?jiǎng)?chuàng)建 hash map入宦,在 _read_images 方法中傳進(jìn)來的參數(shù)都是 NO,也就是說不會(huì)主動(dòng)創(chuàng)建 hash map室琢。我們?nèi)炙阉饕幌?remappedClasses乾闰,可以發(fā)現(xiàn)確實(shí)有地方調(diào)用的時(shí)候 傳入的參數(shù)是 YES:

static void addRemappedClass(Class oldcls, Class newcls) {
...
    old = NXMapInsert(remappedClasses(YES), oldcls, newcls);
...
}

可以發(fā)現(xiàn)確實(shí)創(chuàng)建了,也就是我們前文所說的 addRemappedClass 方法盈滴。那

什么時(shí)候調(diào)用 addRemappedClass 方法涯肩?

但是并不是所有情況下都會(huì)調(diào)用到,只要查看一下函數(shù) readClass 的實(shí)現(xiàn)就知道:

本文暫不做介紹了巢钓,后面的文章中會(huì)給大家介紹病苗。

總結(jié)

本文終于又講完一個(gè) hashmap:remapped_class_map。其實(shí)說白了很簡(jiǎn)單症汹,remapped_class_map 就是存儲(chǔ)了 non-lazy classes 的

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末硫朦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子背镇,更是在濱河造成了極大的恐慌咬展,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芽世,死亡現(xiàn)場(chǎng)離奇詭異挚赊,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)济瓢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妹卿,“玉大人旺矾,你說我怎么就攤上這事《峥耍” “怎么了箕宙?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铺纽。 經(jīng)常有香客問我柬帕,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任陷寝,我火速辦了婚禮锅很,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凤跑。我一直安慰自己爆安,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布仔引。 她就那樣靜靜地躺著扔仓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪咖耘。 梳的紋絲不亂的頭發(fā)上翘簇,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音儿倒,去河邊找鬼缘揪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛义桂,可吹牛的內(nèi)容都是我干的找筝。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼慷吊,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼袖裕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起溉瓶,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤急鳄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后堰酿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疾宏,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年触创,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了坎藐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡哼绑,死狀恐怖岩馍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抖韩,我是刑警寧澤蛀恩,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站茂浮,受9級(jí)特大地震影響双谆,放射性物質(zhì)發(fā)生泄漏壳咕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一顽馋、第九天 我趴在偏房一處隱蔽的房頂上張望谓厘。 院中可真熱鬧,春花似錦趣避、人聲如沸庞呕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽住练。三九已至,卻和暖如春愁拭,著一層夾襖步出監(jiān)牢的瞬間讲逛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國打工岭埠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盏混,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓惜论,卻偏偏與公主長得像许赃,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子馆类,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354