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 屬於小端模式,內存地址倒着讀