美文网首页
方法调用以及转发流程

方法调用以及转发流程

作者: 北京好挤 | 来源:发表于2019-03-19 19:30 被阅读0次

首先理解几个名词:

1.SEL :Objective-C 在编译时,会根据方法的名字生成一个用来区分这个方法的唯一的一个ID,本质上就是一个字符串。只要方法名称相同,那么它们的ID就是相同的。

2.Method:

3.IMP

方法调用查找流程

检查 selector 是否需要忽略

检查 target 是否为 nil,如果是 nil 就直接 cleanup,然后 return

在 target 的 Class 中根据 selector 去找 IMP

寻找 IMP 的过程[2]:

在当前 class 的方法缓存里寻找(cache methodLists)

找到了跳到对应的方法实现,没找到继续往下执行

从当前 class 的 方法列表里查找(methodLists),找到了添加到缓存列表里,然后跳转到对应的方法实现;没找到继续往下执行

从 superClass 的缓存列表和方法列表里查找,直到找到基类为止

以上步骤还找不到 IMP,则进入消息动态处理和消息转发流程

方法转发流程

1.消息动态处理

voiddynamicMethodIMP(idself, SEL _cmd)

{// implementation ....}

+ (BOOL)resolveInstanceMethod:(SEL)sel

{

NSLog(@"sel is %@",NSStringFromSelector(sel));

if(sel ==@selector(setName:))

 class_addMethod([selfclass],sel,(IMP)dynamicMethodIMP,"v@:");

returnYES; 

 }

return [superresolveInstanceMethod:sel];

}

- (id)forwardingTargetForSelector:(SEL)aSelector

{

//如果代理对象能处理,则转接给代理对象if([proxyObj respondsToSelector:aSelector]) {returnproxyObj;

 }

//不能处理进入转发流程returnnil;

}

2.消息转发

<pre>

- (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector{NSMethodSignature*sig = [BBMessageForwardProxy instanceMethodSignatureForSelector:@selector(bb_dealNotRecognizedMessage:)];returnsig;}- (void)forwardInvocation:(NSInvocation*)anInvocation{NSString*debugInfo = [NSStringstringWithFormat:@"[debug]unRecognizedMessage:[%@] sent to [%@]",NSStringFromSelector(anInvocation.selector),NSStringFromClass([selfclass])];//重定向方法[anInvocation setSelector:@selector(bb_dealNotRecognizedMessage:)];//传递调用信息[anInvocation setArgument:&debugInfo atIndex:2];//BBMessageForwardProxy对象接收转发的消息并打印调用信息[anInvocation invokeWithTarget:[BBMessageForwardProxy new]];}

</pre>

如果 methodSignatureForSelector 返回的NSMethodSignature 是 nil 的话不会继续执行 forwardInvocation,转发流程终止,抛出无法处理的异常。

Class和MetaClass

当我们对一个实例发送消息时(-开头的方法),会在该 instance 对应的类的 methodLists 里查找。

当我们对一个类发送消息时(+开头的方法),会在该类的 MetaClass 的 methodLists 里查找。

load和initialize

我们知道了 load 是在被添加到 runtime 时开始执行,父类最先执行,然后是子类,最后是 Category。又因为是直接获取函数指针来执行,不会像 objc_msgSend 一样会有方法查找的过程。

initialize 最终是通过 objc_msgSend 来执行的,objc_msgSend 会执行一系列方法查找,并且 Category 的方法会覆盖类中的方法。

category

相关文章

  • 方法调用以及转发流程

    首先理解几个名词: 1.SEL :Objective-C 在编译时,会根据方法的名字生成一个用来区分这个方法的唯一...

  • iOS消息转发机制

    OC消息转发 oc中的调用对象或者类不存在的方法,会执行一遍消息转发流程.消息转发主要包括4步 首先调用+ (BO...

  • Runtime:objc_msgSend

    目录一,基本流程二,消息发送三,动态方法解析四,消息转发 一,基本流程 1,方法的调用都会转换为objc_msgS...

  • Runtime入门总结

    简介Runtime的基础数据结构消息发送1. 方法调用流程2. 动态方法解析3. 快速转发4. 标准转发API使用...

  • Runtime-(五)消息转发流程

    我们先来看看实例方法的消息转发流程 这里来说明一下流程 先调用resolveInstanceMethod:这个类方...

  • iOS runtime,详细介绍消息转发流程

    iOS runtime,详细介绍消息转发流程 方法查找原理 在之前的文章中,写过在进行方法调用的时候,runtim...

  • 运行时

    运行时 调用 消息转发 通过 obj_msgSend 调用,在找不到imp的时候,就会进入消息转发流程 调用 + ...

  • iOS Runtime详解及应用场景

    一 runtime简介 二 Class的结构 三 isa指针详解 四 method详解 五 方法调用及消息转发流程...

  • OC方法调用流程及消息转发

    objc_msgForward函数的作用objc_msgForward是 IMP 类型,用于消息转发的:当向一个对...

  • Runtime消息转发

    消息转发是在查找IMP失败后执行一系列转发流程。 ①动态方法解析: 对象在收到无法解读的消息之后,首先将调用所属类...

网友评论

      本文标题:方法调用以及转发流程

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