在iOS中調用一個方法,實際上是調用一個方法實現的函數指針並傳給他對象實例指針,一個Selector,還有函數用到的參數。在Objective-C 中,每個方法調用其實都是轉換成了調用objc_msgSend方法。 緩存
objc_msgSend的調用過程以下: 函數
0)首先檢查消息接受對象是否爲nil. 若是消息接受對象爲nil,則觸發nil-handler. 默認nil-handler是什麼都不作的。 指針
1)在垃圾回收環境中(Mac OS X)中,檢查是否調用了(retain, release, autorelease, retainCount), 若是是,就返回self. 因此,這就意味着在垃圾回收機制中,retainCount 返回self。這時調用retainCount就會產生無限循環。 對象
2)檢查class的緩存中是否有該方法的實現,若是有,調用。 get
3)在類方法中是否有該方法,若是有就調用類方法的實現。 io
4)查看父類中是否有該方法實現,若是沒有再查找父類的父類中有沒有實現。若是找到了,調用。 class
5)調用resolveInstanceMethod:(或者resolveClassMethod:). 若是返回YES, 則調用。 該對象會有該方法的實現,由於它會調用class_addMethod. 垃圾回收
6) 調用forwardingTargetForSelector:. 若是返回non-nil, 則對返回對象發消息。此處不會返回self,不然會進入無限循環。 循環
7)調用methodSignatureForSelector:, 若是返回non-nil, 建立一個NSInvocation 而且將這個NSInvocation傳遞給forwardInvocation:. 方法
8) 調用doesNotRecognizeSelector:. 默認實現就是拋一個異常。