iOS 消息传递过程解析

在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的缓存中是否有该方法的实现,如果有,调用。

3)在类方法中是否有该方法,如果有就调用类方法的实现。

4)查看父类中是否有该方法实现,如果没有再查找父类的父类中有没有实现。如果找到了,调用。

5)调用resolveInstanceMethod:(或者resolveClassMethod:). 如果返回YES, 则调用。 该对象会有该方法的实现,因为它会调用class_addMethod.

6) 调用forwardingTargetForSelector:. 如果返回non-nil, 则对返回对象发消息。此处不会返回self,否则会进入无限循环。

7)调用methodSignatureForSelector:, 如果返回non-nil, 创建一个NSInvocation 并且将这个NSInvocation传递给forwardInvocation:.

8) 调用doesNotRecognizeSelector:. 默认实现就是抛一个异常。