OC的消息机制
系统内部都是靠objc_msgSend来实现方法调用的在Objective-C中,message与方法的真正实现是在执行阶段绑定的,而非编译阶段,编译器会将消息发送转换成objc_msgSend 方法的调用。objc_msgSend方法含有两个必要参数:receiver、 方法名(即selector)。如:[receiver message]; 将被转换为: objc_msgSend(receiver selector); objc_msgSend方法也 能hold住message参数,如:objc_msgSend(receiver ,selector, arg1,arg2,…);
objc_msgSend方法会按照顺序进行以下操作, 以完成动态绑定:查找selector所指代的程序(方法的真正实 现)。因为不同类对同一方法有不同的实现,所以对方法的真正 实现的查找依赖于receiver的类调用该实现,并将一系列参数 传递过去将实现的返回值作为自己的返回值,返回值消息传递 的关键是,编译器构建每个类和对象所采用的数据结构、每个 类都包含以下两个必要元素:一个指向父类的指针一个调度表 ( d i s p a t c h t a b l e )。 该 调 度 表 将 类 的 s e l e c t o r 与 方 法 的 实 际 内 存地址关联起来。每个对象都有一个指向所属类的指针isa。通过该指针,对象可以找到它所属的类,也就找到了其全部父类。
Runtime 如何通过selector找到相对应的IMP地址?
:类对象中有类方法和实例方法的列表,列表中记录着方法名,参数,和方法实现(实例方法存在于类对象中,类方法存在于元类方法中).
SEL就是方法名,IMP就是implementation,是指向方法实现函数的指针.
举个例子说明一下SEL和IMP的关系:以一本书的目录为例,SEL就是文章名 IMP就是对应的页码 。
当发消息时,如果是实例方法,会通过isa去类对象中的方法列表中查找对应的IMP,如果是类方法,会通过isa去元类对象中的方法列表中查找对应的IMP。