runtime NSProxy 消息转发

作者: jing091111 | 来源:发表于2017-04-10 17:17 被阅读27次

    oc中调用方法其实就是向对象发送消息,在编译Objective-C函数调用的语法时,会被翻译成一个C的函数调用:objc_msgSend(),例如:

    那么,objc_msgSend又做了哪些事呢?,以[object foo]为例:

    1.通过object的isa指针找到它的class

    2.在class的method_list中找到foo

    3.如果class中没找到foo,则继续往他的superclass中查找

    4.一旦找到foo这个函数,就去执行对应的方法实现(IMP)

    NSMethodSignature(方法签名)

    方法签名:用语记录一个方法的参数和返回值类型的类。类似于objc_method_description结构体。方法签名是用于初始化NSInvocation用的。

    NSInvocation

    用于记录一个消息(方法)的接收者(target)方法名(SEL)参数类型,参数等信息,包含执行该消息方法的类。

    此类类似于结构体Method。

    他提供了- (void)invokeWithTarget:(id)target;调用对象中的方法。类似于id method_invoke(id receiver, Method m, …) 函数。

    注意:NSMethodSignature,NSInvocation一般我们都是用语消息转发时候用到。正常我们用的比较少。

    二、动态方法决议与消息转发

    消息转发机制基本上分为三个步骤:

    1. 动态方法解析:- (BOOL)resolveInstanceMethod:(SEL)sel;+ (BOOL)resolveClassMethod:(SEL)sel 返回添加新方法并YES

    2. 备用接收者

    -(id)forwardingTargetForSelector:(SEL)aSelector 

    如果一个对象实现了这个方法,并返回一个非nil的对象,则返回的对象会作为消息的新接收者,且消息会被分发到这个对象。当然这个对象不能是self自身,否则就是出现无限循环。当然,如果我们没有指定相应的对象来处理aSelector,则应该调用父类的实现来返回结果。

    3. 完整转发

    如果在上一步还不能处理未知消息,则唯一能做的就是启用完整的消息转发机制了。

    此时会调用以下方法:

    -(void)forwardInvocation:(NSInvocation*)anInvocation

    由于NSInvocation的初始化需要有一个方法签名NSMethodSignature,所以我们还需要实现下面的方法,该方法的返回值用于初始化NSInvocation的。

    -(NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector

    methodSignatureForSelector用来生成方法签名,这个签名就是给forwardInvocation中的参数NSInvocation调用的。

    相关文章

      网友评论

        本文标题:runtime NSProxy 消息转发

        本文链接:https://www.haomeiwen.com/subject/qoasattx.html