前言
- 目前打算深入一下OC和Swift的底層探究剂碴,希望自己有所提升蹦渣,并能分享一些收獲球拦。
這篇主要記錄:通過查看objc的源碼探索alloc&init
- 在這里給大家介紹一位大牛已經(jīng)配置好的源碼GitHub蔚鸥,我們直接下載就可以使用了动雹。
1. 下載之后焰薄,經(jīng)過一些配置拿诸,真機編譯 ,然后來到如下調(diào)試界面
注:allocwithZone 基本被舍棄沒用了塞茅;一般情況下 alloc 和 allocwithZone 的作用是一樣的亩码,alloc和allocWithZone都可以用于創(chuàng)建實例,實際上alloc會默認調(diào)用allocWithZone方法野瘦;
2.接下來我們來到:_class_createInstanceFromZone
(類從區(qū)域創(chuàng)建實例)方法里面 這里有三個重要步驟
注:
- a. 可以發(fā)現(xiàn)alloc具有
申請內(nèi)存空間
描沟、創(chuàng)建對象
、并給指針賦予地址的能力
; - b. 獲取實例的內(nèi)存空間大小:
cls->instanceSize()
- c. 根據(jù)內(nèi)存大小鞭光,分配內(nèi)存空間吏廉,讓實例指向內(nèi)存開始地址:
calloc
- d.
關聯(lián)isa
,實例的isa指向類:obj->initInstanceIsa(cls, hasCxxDtor)
- e:關于
word_align
字節(jié)對齊(x + WORD_MASK) & ~WORD_MASK
這個算法是為了讓isa
對象需要的內(nèi)存空間是8的倍數(shù)-8字節(jié)對齊惰许,mallocSize
系統(tǒng)分配的內(nèi)存大小是16字節(jié)對齊的計算屬性方法等席覆。作用:內(nèi)存對齊,讓CPU讀取更加方便,用空間來換取時間
3 .總結alloc 全部流程(來自百度):
4.探索init汹买,new方法
id _objc_rootInit(id obj)
{
return obj;
}
返回的就是alloc出來的obj佩伤。
- (id)init {
return _objc_rootInit(self);
}
init沒做任何操作,一般在這里是工廠方式來重寫方法晦毙,自定義畦戒,我們經(jīng)常會這樣寫代碼
- (instancetype)init{
self = [super init];
if (self) {
[self doSomething];
}
return self;
}
//
[super init] 重寫父類的方法 防止覆蓋父類的方法
self = [super init]
= 是確認繼承父類 可以延伸自己的方法
if(self)做判斷處理 防止父類在init的時候return nil
做一個安全的處理 不然子類的實現(xiàn)就沒有意義了
通過源碼,看出new
就是callAlloc
+init
的組合實現(xiàn)
+ (id)new {
return [callAlloc(self, false/*checkNil*/) init];
}
5. 拓展:
-
編譯優(yōu)化
:fastpath 结序、slowpath 進行是否需要編譯優(yōu)化的判斷 障斋,release模式下都會進行編譯優(yōu)化,執(zhí)行fastpath判斷,作用
:減少編譯時間垃环,鏈接時間邀层,運行時間,優(yōu)化空閑時間遂庄;
轉載:iOS 查看項目編譯時間并優(yōu)化編譯速度方法 - 打印語句記錄:
po
與p
:p
表示"expression
"——打印對象指針;
po
是"expression -O
"——打印對象本身;
x/4gx
對象 ——表示輸出4個16進制的8字節(jié)地址空間(x表示16進 制寥院,4表示4個,g表示8字節(jié)為單位涛目,等同于x/4xg 對象);
x 對象——表示以16進制打印對象內(nèi)存地址(x表示16進制);
6. 總結:
通過查看objc的源碼探索alloc&init秸谢,我們可以大致看清alloc的執(zhí)行步驟,這篇主要講了其整體的流程霹肝,主要核心就是來到_class_createInstanceFromZone
估蹄,這個方法告訴我們內(nèi)存是如何開辟的,內(nèi)存是如何分配的沫换,當前類和指針地址的關系臭蚁。接下再來深入探索,開辟分配內(nèi)存的細節(jié)和對象中的屬性對內(nèi)存分配的影響讯赏。