runtime基础教程(2)-OC的消息传递
2016-03-08 11:15
176 查看
基本消息传递
在面向对象编程中,对象调用方法叫做发送消息。在编译时,程序的源代码就会从对象发送消息转换成Runtime的objc_msgSend函数调用。// 例如某实例变量person实现某一个方法eat [person eat]; // Runtime会将其转成类似这样的代码 objc_msgSend(person, selector); // 具体会转换成什么代码呢? Runtime会根据类型自动转换成下列某一个函数: objc_msgSend:普通的消息都会通过该函数发送 objc_msgSend_stret:消息中有数据结构作为返回值(不是简单值)时,通过此函数发送和接收返回值 objc_msgSendSuper:和objc_msgSend类似,这里把消息发送给父类的实例 objc_msgSendSuper_stret:和objc_msgSend_stret类似,这里把消息发送给父类的实例并接收返回值
objc_msgSend函数的调用过程:
第一步:检测这个selector是不是要忽略的。
第二步:检测这个target是不是nil对象。nil对象发送任何一个消息都会被忽略掉。
第三步:
1.调用实例方法时,它会首先在自身isa指针指向的类(class)methodLists中查找该方法,如果找不到则会通过class的super_class指针找到父类的类对象结构体,然后从methodLists中查找该方法,如果仍然找不到,则继续通过super_class向上一级父类结构体中查找,直至根class;
2.当我们调用某个某个类方法时,它会首先通过自己的isa指针找到metaclass,并从其中methodLists中查找该类方法,如果找不到则会通过metaclass的super_class指针找到父类的metaclass对象结构体,然后从methodLists中查找该方法,如果仍然找不到,则继续通过super_class向上一级父类结构体中查找,直至根metaclass;
第四部:前三步都找不到就会进入动态方法解析(看下文)。
消息动态解析
动态解析流程图(图片来自网络):第一步:通过resolveInstanceMethod:方法决定是否动态添加方法。如果返回Yes则通过class_addMethod动态添加方法,消息得到处理,结束;如果返回No,则进入下一步;
第二步:这步会进入forwardingTargetForSelector:方法,用于指定备选对象响应这个selector,不能指定为self。如果返回某个对象则会调用对象的方法,结束。如果返回nil,则进入第三部;
第三部:这步我们要通过methodSignatureForSelector:方法签名,如果返回nil,则消息无法处理。如果返回methodSignature,则进入下一步;
第四部:这步调用forwardInvocation:方法,我们可以通过anInvocation对象做很多处理,比如修改实现方法,修改响应对象等,如果方法调用成功,则结束。如果失败,则进入doesNotRecognizeSelector方法,若我们没有实现这个方法,那么就会crash。
相关文章推荐
- MinGW main()
- JS事件委托的原理和应用
- PAT1047编程团体赛(20)
- [Offer收割]编程练习赛1 hihocoder 1271 舰队游戏 (状态压缩+贪心 好题)
- Makefile中的-Wall -O2 -Os -g等选项介绍
- 越维护代码越感觉心惊肉跳的
- saiku 展示优化第二步(要诀和技巧)
- widget
- 19.CoreMotion(陀螺仪)
- Leetcode:172. Factorial Trailing Zeroes(JAVA)
- 一幅图秒懂LoadAverage(负载)
- TabLayout-Android M新控件
- SNMP的5种协议数据单元
- RecyclerView
- saiku 展示优化第二步(要诀和技巧)
- java创建线程的2种方式
- 存储构造题(Print Check)
- C#实现性能计数器
- 20160308 C#代码实现Excel数据导入到SQL Server数据库中
- 2015 年最棒的 5 个 HTML5 框架