runtime怎么实现方法的调用 :消息机制,runtime系统会把方法调用转化为消息发送。即objc-msgSend。并把方法的调用者和方法选择器当做参数传递过去,这也是我们为什么在方法中可以使用self的原因。
objc_msgSend的执行流程可以分为3大阶段:
1.首先检测这个selector是不是要忽略像mac osx开发,有了垃圾回收就不会理会retain,release函数
2.检测这个selector的target是不是nil.objc允许我们向一个nil对象执行任何方法不会Crash,因为运行时会查找该对象的isa指针,直接就0地址返回了.
3,如果上面两步都通过,就直接查找这个类的实现IMP,为了效率,优先在cache中查找,找到后就跳到对应的方法中执行。
4.如果cache找不到,就在类的methodLists(实例方法))中查找,如果找到了就调用方法,结束查找,并将方法缓存到receiveClass的cache中
5.如果类的方法列表中找不到就通过superclass指针往上一级超类查找(类方法存放在元类中、Class通过isa指针即可找到其所属的元类),找到了,就结束查找并将方法缓存到receiveClass的cache中,没找到一直找到NSObject类为止
6.如果还是找不到,就会进入动态方法解析
在对象收到无法处理的消息之后,会执行消息转发,消息转发有三个步骤:
1调用 resolveInstanceMethod 方法。动态方法解析,这里会给类使class_addMethod 来增加方法的机会。
2调用 forwardingTargetForSelector 方法,看是否有备用接收者,将消息转发给备用接收者处理。
3调用 methodSignatureForSelector 和 forwardInvocation 方法,进行完成的消息转发。