iOS中执行方法过程
2018-04-07 本文已影响12人
CoderLF
一、执行方法
- 首先通过obj的isa指针找到obj对应的class。
- 然后检测这个 selector 是不是要忽略。比如 Mac OS X 开发,有了垃圾回收就不理会 retain,release 这些函数。
- 检测这个 selector 的 target 是不是 nil,Objc 允许我们对一个 nil 对象执行任何方法不会 Crash,因为运行时会被忽略掉。
- 如果上面两步都通过了,那么就开始查找这个类的实现 IMP,
在Class中先去cache中 通过SEL查找对应函数method,找到就执行对应的实现。 - 若cache中未找到,再去methodList中查找,找到就执行对应的实现。
- 若methodlist中未找到,则取superClass中查找(重复执行以上两个步骤),直到找到最根的类为止。
- 若任何一部能找到,则将method加 入到cache中,以方便下次查找,并通过method中的函数指针跳转到对应的函数中去执行。
- 如果以上都不能找到,则会开始进行消息转发
二、消息转发
- 动态方法解析:向当前类发送 resolveInstanceMethod: 信号,检查是否动态向该类添加了方法。(迷茫请搜索:@dynamic)
- 快速消息转发:检查该类是否实现了 forwardingTargetForSelector: 方法,若实现了则调用这个方法。若该方法返回值对象非nil或非self,则向该返回对象重新发送消息。
- 标准消息转发:runtime发送methodSignatureForSelector:消息获取Selector对应的方法签名。返回值非空则通过forwardInvocation:转发消息,返回值为空则向当前对象发送doesNotRecognizeSelector:消息,程序崩溃退出
总结就是: 在一个函数找不到时,OC提供了三种方式去补救:
1、调用resolveInstanceMethod给个机会让类添加这个实现这个函数
2、调用forwardingTargetForSelector让别的对象去执行这个函数
3、调用forwardInvocation(函数执行器)灵活的将目标函数以其他形式执行。 如果都不中,调用doesNotRecognizeSelector抛出异常。