1.isa指针:每个objc对象都有一个isa指针,指向其类对象,从而可以找到类对象上的方法列表。
2.[obj foo] 与 objc_msgSend(obj,@selector(foo))关系
[obj foo];在编译时,会被转意为:obc_msgSend(obj,@selector(foo));
3.objc_msgSend(obj,foo)的过程:
首先:通过obj的isa指针找到它的class;
然后:在class的method_list中找foo;
其次:如果class中没找到foo,继续往它的superclass中找;
最后:找到foo这个函数,就去执行它的IMP.
4.如果objc_msgSend最终没有找到foo,这是就涉及到objc_msgForward:
runtime会提供3次拯救程序的机会:
1)Method Resolution;
2)Fast Forwarding;
3)Normal Forwarding;
①Method Resolution
首先,runtime会调用+resolveInstanceMethod:或者+resolveClassMethod:,让你有机会提供一个函数实现。如果添加了函数并返回yes,runtime就会重新启动一次消息发送的过程。
如果返回no,就会移到下一步:Message Forwarding(消息转发)。
②Fast Forwarding
如果目标对象实现了-forwardingTargetForSelector:,runtime就会调用这个方法, 给你把这个消息转发给其他对象的机会。只要这个方法返回的不是nil和self,整个消息发送的过程就会被重启,发送的对象会变成你返回的那个对象。否则,就会进入Normal Forwarding。这里叫Fast,只是为了区别下一步的转发机制。因为这一步不会创建新对象,所以相对更快。
③Normal Forwarding
首先,它会发送-methodSignatureForSelector:消息获得函数的参数和返回值类型。如果返回nil,则会发出-doesNotRecognizeSelector:消息,程序崩溃。
如果返回了一个函数签名,runtime就会创建一个NSInvocation对象并发送-forwardInvocation:消息给目标对象。