OC 對象原理(1)- 對象的建立(隨記)

1、alloc 探索---查找alloc源碼所在位置sass

先給出一段代碼
複製代碼
LGPerson *p1 = [LGPerson alloc];
    LGPerson *p2 = [p1 init];
    LGPerson *p3 = [p1 init];
    LGNSLog(@"%@ - %p",p1,&p1);
    LGNSLog(@"%@ - %p",p1,&p2);
    LGNSLog(@"%@ - %p",p1,&p3);
複製代碼

打印結果:bash

<LGPerson: 0x6000016c6260> - 0x7ffee49c8178app

<LGPerson: 0x6000016c6260> - 0x7ffee49c8170post

<LGPerson: 0x6000016c6260> - 0x7ffee49c8168spa

從結果能夠總結爲,p1,p2,p3 指向同一個內存空間,但建立出來的三個對象的指針地址是不一樣的。設計

以此咱們可能就會產生以下幾個疑問:3d

一、爲何會出現這個打印結果呢?指針

由於 alloc 建立實例對象的同時也申請了一塊內存空間,p1,p2,p3是分配的3個對象的指針,所以 p1,p2,p3 屬於同一個對象並都指向這塊內存空間。調試

二、alloc 又是怎麼實現的呢?code

咱們經過分析alloc源碼來尋找這個問題的答案,有以下三種方式來知道alloc源碼所在的動態庫,libobjc.A.dylib:

1)第一種方式:真機調試,打斷點

在如圖所示打上斷點,而後按住 ‘control’的同時點擊箭頭所指的按鈕進入,再繼續點擊此按鈕,直到出現 libobjc.A.dylib

2)第二種方式:選擇Symbolic Breakpoint ,在Symbol這欄輸入 alloc 也能獲得想要的答案。

而後出現不少不少實現了alloc方法的斷點,再次真機運行

此時再點擊上圖箭頭所指的按鈕以後也會出現

3)第三種方法:經過彙編 選擇->Debug->Debug Workflow -> Always Show Disassembly,再次在真機上運行,此時會直接跳轉到彙編界面

在其中咱們照樣能夠找到 objc_alloc,而後將斷點下的此處,再按住 control 鍵,點擊下圖箭頭所指按鈕

一直按直到出現以下圖所示,出現alloc所在的動態庫名

三、建立對象的過程當中與init的關係是什麼呢?

由上圖 init 的源碼可看出,init什麼也沒作,只是提供了一個初始化方法,方便咱們重寫,由咱們本身隨意發揮,工廠設計的模式

由上圖得出new跟 alloc->init 同樣的效果

2、alloc探索---下載並配置alloc所在的動態庫開源的源碼(objc)

源碼下載地址:opensource.apple.com/tarballs/

源碼編譯調試參考點擊

3、alloc探索--分析查看 alloc 源碼流程

1)alloc 流程圖

部分源碼解釋

calloc : 申請對象和開闢內存空間

initInstanceIsa :關聯內存指針

2)申請內存空間(字節對齊)

size:申請的內存空間大小,對象自帶內存大小 8 字節(Class isa)

a.對象內存空間規則 8 字節對齊(目的:提升 cpu 讀取速度,以空間換取時間)

b.內存所佔空間小於16字節時,最少16字節,爲了防止讀取或存儲時越界

查看內存空間結構:

由上圖可知:棧點指針起始位置爲isa

打印指令:

x [對象名] :查看對象的存儲空間,以16進制打印內存空間

x/[n]xg [對象名] : 以16 進制讀取 n 個內存段

register read :讀寄存器

隨記:

x0:是第一個參數的傳遞者,也是返回值存儲的地方(isa)

iOS 屬於小端模式,內存地址倒着讀

相關文章
相關標籤/搜索