IOS底層(五): alloc相關(guān): NSObject, alloc源碼分析

OC底層源碼/原理合集

建議先看下 IOS底層(三): alloc相關(guān)1.初探 alloc, init, new源碼分析

先看個(gè)例子


exp1
exp2

NSObject , alloc方法里面 加斷點(diǎn), 運(yùn)行我們會(huì)發(fā)現(xiàn)竟然沒有走+ (id)alloc方法

那么NSObject在走的是哪個(gè)方法呢?

打開 DebugDebug Workflow勾選 Always Show Disassemly進(jìn)行匯編調(diào)試

alloc方法這邊打個(gè)斷點(diǎn), 運(yùn)行一下

exp3
exp4

我們可以看到都走了一個(gè)objc_alloc 方法
全局搜索 objc_alloc,可看到有一個(gè)這個(gè)方法

exp5

objc_alloc中加一個(gè)斷點(diǎn),先暫時(shí)關(guān)閉匯編, 重新運(yùn)行下可看到, 的確走到這里來了

exp6

那么為什么NSObject走的是objc_alloc(Class cls) 這個(gè)方法?

原因主要是: NSObject 系統(tǒng)級(jí)別幫我們走完

這里我們需要一份LLVM源碼(llvm-project, 是系統(tǒng)級(jí)別的源碼)來具體分析下, objc_alloc是什么時(shí)候有的, 而它又與alloc有什么區(qū)別。
LLVM下載地址

查找下
通過alloc字符串或者omf_alloc:搜索, 找到tryGenerateSpecializedMessageSend方法

llvm查找alloc

這里可以看到, 如果當(dāng)前方法sel如果是alloc就會(huì)調(diào)用一個(gè)EmitObjCAlloc方法, 點(diǎn)進(jìn)去看一下

llvm查找alloc

可以看到這里調(diào)用了一個(gè)objc_alloc。由此可以得出NSObject中的alloc會(huì)走到objc+alloc, 其實(shí)這部分是由系統(tǒng)級(jí)別的消息處理邏輯, 固NSObject的初始化是由系統(tǒng)完成, 因此不會(huì)走傳統(tǒng)的alloc的源碼中。

j接下來我們看下自定義類SATest

NSObject *objc = [NSObject alloc];
SATest *objc1 = [SATest alloc];

首先SATest 是繼承NSObject的, NSObject是其根類/基類/父類, 所有自定義的類都繼承于NSObject。

我們由LLVM已經(jīng)得出, NSObject都會(huì)走一個(gè)objc_alloc方法。那么繼承于NSObject也會(huì)走一個(gè)objc_alloc方法。這個(gè)也是之前我們那張匯編的圖片SATest, 也走了objc_alloc原因

那么問題也出現(xiàn)了
objc_alloccallAlloc 并不應(yīng)該走
alloc_objc_rootAlloc_objc_rootAlloccallAlloc

我們?cè)?code>callAlloc打個(gè)斷點(diǎn)發(fā)現(xiàn), 的確是走了2次, 這就很離譜?

自定義類的callAlloc走了2次

我們?cè)?callAlloc跟一下流程

自定義類objc_alloc走的是objc_msgSend

可看到自定義類中objc_alloc, callAlloc走的是(id, SEL))objc_msgSend)(cls, @selector(alloc));, 即向系統(tǒng)發(fā)送消息, 沒有走_objc_rootAllocWithZone

這里我們需要再看下LLVMGeneratePossiblySpecializedMessageSend消息發(fā)送這里

llvm消息發(fā)送

我們可以看到但凡是runtime的消息發(fā)送必然現(xiàn)在走if判斷, 由于傳入sel@selector(alloc)并沒有走過, 沒有找到所以這里的if判斷是false, 走GenerateMessageSend這個(gè)方法, 即調(diào)用selalloc方法, 即alloc_objc_rootAlloc_objc_rootAlloccallAlloc

總結(jié):

NSObject
7EB02DAA0F471DC24E29A22E94C6A505.jpg
自定義類
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容