Runtime之objc_msgSend和objc_msgForward

    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:消息给目标对象。

你可能感兴趣的:(Runtime之objc_msgSend和objc_msgForward)