alloc&init原理探索

一、調(diào)試方法:

開篇我們先來介紹三種可以進(jìn)入libobjc.A.dylib(objc_alloc所在的動態(tài)庫)的調(diào)試方法,需要用真機(jī)進(jìn)行調(diào)試:

1、直接下斷點(diǎn):斷點(diǎn)在Person *p1 = [Person alloc];行 -> 按住control -> 點(diǎn)擊 step into進(jìn)入;

下斷點(diǎn)

2竹椒、符號斷點(diǎn):

符號斷點(diǎn)

3、通過匯編查看:斷點(diǎn)在Person *p1 = [Person alloc];行匈挖,開啟Always Show Disassembly,如圖:

匯編方式
二碾牌、接下來我們看一段代碼:
Person *p1 = [Person alloc];
Person *p2 = [p1 init];
Person *p3 = [p1 init];
NSLog(@"?%@ - %p",p1,&p1);
NSLog(@"?%@ - %p",p2,&p2);
NSLog(@"?%@ - %p",p3,&p3);

打印結(jié)果如下:

?<Person: 0x600003885d40> - 0x7ffeec2e10c8
?<Person: 0x600003885d40> - 0x7ffeec2e10c0
?<Person: 0x600003885d40> - 0x7ffeec2e10b8

以上我們可以看出p1康愤、p2、p3三個不同的指針指向的是同一片內(nèi)存空間,init大概貌似啥也沒干舶吗。

三征冷、下面我們詳細(xì)看一下初始化對象時常用的alloc/init/new都做了些啥?

準(zhǔn)備工作:源碼下載及配置

1誓琼、 alloc探索

1) 流程圖:

alloc流程圖.png

2) 理解:

  • alloc創(chuàng)建對象并申請內(nèi)存空間检激,也伴隨著給當(dāng)前對象賦予了指針地址;
  • 我們看到alloc后直接走了rootAlloc,而不是objc_alloc,這一部分其實是編譯器幫我們優(yōu)化了腹侣,可以通過llvm源碼來驗證叔收。
  • objc_alloc只走一次,同樣可以通過llvm源碼來驗證傲隶。
  • alloc是否具有創(chuàng)建對象的能力:流程返回的時候x0是否會存儲一個指針饺律,即申請到的內(nèi)存空間。
  • x0即是第一個參數(shù)的傳遞者跺株,也是返回值的存儲地方(傳遞口)复濒。注意下面這個類方法:
    + (id)alloc {
    return _objc_rootAlloc(self); // self即Person
    }
    

3) 分支流程:

a、 hasCustomAWZ():判斷當(dāng)前方法是否有默認(rèn)的allocWithZone乒省;
b巧颈、canAllocFast():這里最終直接返回false,順著源碼具體分析一下:

  • 順著canAllocFast點(diǎn)進(jìn)去:
bool canAllocFast() {
       assert(!isFuture());
       return bits.canAllocFast();
}
  • Next:
#if FAST_ALLOC
   // 省略代碼

    bool canAllocFast() {
        return bits & FAST_ALLOC;
    }
#else
    // 省略代碼
   // 一般會走這里
    bool canAllocFast() {
        return false;
    }
#endif
  • 可以看到FAST_ALLOC是定義在另一個宏里的:
#if !__LP64__
// .....
#elif 1
// .....
// 一般會走這里
#else
// .....
#define FAST_ALLOC              (1UL<<2)

#endif
  • 可以判斷上面的宏只走#elif 1中的代碼袖扛,即FAST_ALLOC一直沒有被define砸泛,那么我們倒推一下就很容易理解為什么canAllocFast()直接返回false了。

c蛆封、來到_class_createInstanceFromZone中:

  • bool hasCxxCtor = cls->hasCxxCtor();是否有C++構(gòu)造函數(shù)唇礁。
  • bool hasCxxDtor = cls->hasCxxDtor();是否有C++析構(gòu)函數(shù)。
  • bool fast = cls->canAllocNonpointer();是否創(chuàng)建nonpointer,這里為true娶吞。
  • size_t size = cls->instanceSize(extraBytes); 申請內(nèi)存垒迂,這里有一個字節(jié)對齊的知識點(diǎn)。
  • obj = (id)calloc(1, size);系統(tǒng)根據(jù)申請到的內(nèi)存大小去開辟相對應(yīng)的內(nèi)存空間給obj對象妒蛇,更進(jìn)一步的代碼需要去malloc源碼中去查看机断。
  • initInstanceIsa創(chuàng)建對象。
//  字節(jié)對齊:至少16字節(jié)
size_t instanceSize(size_t extraBytes) {
        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        if (size < 16) size = 16;
        return size;
    }

2绣夺、init探索
這里可以看到返回的是alloc中創(chuàng)建的obj吏奸,主要作用是預(yù)留給開發(fā)者在工廠模式中重寫初始化方法,方便自定義以及擴(kuò)展陶耍。

+ (id)init {
    return (id)self;
}

3奋蔚、new探索

+ (id)new {
    return [callAlloc(self, false/*checkNil*/) init];
}
四、LLDB命令
  • register read: 讀取當(dāng)前寄存器;
  • x/4xg p: 以16進(jìn)制截取4段,這里也可以是5xg泊碑、6xg坤按;

如有不當(dāng),歡迎指正馒过,感謝臭脓。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市腹忽,隨后出現(xiàn)的幾起案子来累,更是在濱河造成了極大的恐慌,老刑警劉巖窘奏,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘹锁,死亡現(xiàn)場離奇詭異,居然都是意外死亡着裹,警方通過查閱死者的電腦和手機(jī)领猾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來求冷,“玉大人瘤运,你說我怎么就攤上這事窍霞〗程猓” “怎么了?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵但金,是天一觀的道長韭山。 經(jīng)常有香客問我,道長冷溃,這世上最難降的妖魔是什么钱磅? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮似枕,結(jié)果婚禮上盖淡,老公的妹妹穿的比我還像新娘。我一直安慰自己凿歼,他們只是感情好褪迟,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著答憔,像睡著了一般味赃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上虐拓,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天心俗,我揣著相機(jī)與錄音,去河邊找鬼。 笑死城榛,一個胖子當(dāng)著我的面吹牛揪利,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播狠持,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼土童,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了工坊?” 一聲冷哼從身側(cè)響起献汗,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎王污,沒想到半個月后罢吃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昭齐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年尿招,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阱驾。...
    茶點(diǎn)故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡就谜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出里覆,到底是詐尸還是另有隱情丧荐,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布喧枷,位于F島的核電站虹统,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏隧甚。R本人自食惡果不足惜车荔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望戚扳。 院中可真熱鬧忧便,春花似錦、人聲如沸帽借。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宜雀。三九已至切平,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間辐董,已是汗流浹背悴品。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人苔严。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓定枷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親届氢。 傳聞我的和親對象是個殘疾皇子欠窒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評論 2 354

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