我們知道在 Objective-C 中給 nil 發送消息程序不會崩潰,
Objective-C 是以 C 語言為基礎的,
PC 上,在 C 語言中對空指針進行操作,
程序會由於越界訪問而出現保護錯進而崩潰,
但是 Objective-C 中為什么不會崩潰呢?
原因需要從源代碼中尋找,
下面是 objc_msgSend 的 arm 版匯編代碼片段:
在 arm 的函數調用過程中,
一般用 r0-r4 傳遞參數,
用 r0 傳遞返回值。
對應 objc_msgSend,第一個參數為 self,返回值也是 self,都放在 r0(a1)中。
/********************************************************************
* idobjc_msgSend(idself, SELop, ...)
* On entry: a1 is the message receiver,
* a2 is the selector
********************************************************************/
ENTRY objc_msgSend
# check whether receiver is nil
teq a1, #0
moveq a2, #0
bxeq lr
teq 指令說明:
TEQ Rn, Operand2 The TEQ instruction performs a bitwise Exclusive OR operation on the value in Rn and the value of Operand2.
測試 self 是否為空。
moveq 指令說明:
如果self為空,則將 selector 也設置為空。
bx 指令說明:
在 arm 中 bx lr 用來返回到調用子程序的地方(即:返回到調用者),此處是:如果 self 為空,就返回到調用 objc_msgSend 的地方繼續執行。
總之:
如果傳遞給 objc_msgSend 的 self 參數是 nil,該函數不會執行有意義的操作,直接返回。
