我們知道在 Objective-C 中給 nil 發送訊息程式不會崩潰,
Objective-C 是以 C 語言為基礎的,
PC 上,在 C 語言中對null 指標進行操作,
程式會由于越界訪問而出現保護錯進而崩潰,
但是 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
R
n
, 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,該函數不會執行有意義的操作,直接返回。