相对而不绝对

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

   OC 是面向运行时的语言。Runtime就是系统在运行的时候的一些机制,其中最主要的是消息发送机制。OC语言与其他语言(如C语言)在函数(方法)的调用有很大的不同。C语言,函数的调用在编译的时候就已经决定调用哪个函数,编译完成之后直接顺序执行。而对于OC言,方法的调用则不然,在编译的时候不决定调用哪个方法。因为OC的方法调用是消息发送,属于动态调用过程,只有在真正运行的时候才会根据方法的名称找到对应的方法来调用。

OC是怎么实现动态调用的呢?

[obj start];

obj是对象,start是方法名。在编译时Runtime会将上述的代码转化为:

1 objc_msgSend(obj,@selector(start));

OC中所有的对象都继承于NSObject

1 @interface NSObject <NSObject> {
2     Class isa  OBJC_ISA_AVAILABILITY;
3 }

在NSObject中存在一个Class的isa指针。下面介绍这个Class:

 1 struct objc_class {
 2     Class isa  OBJC_ISA_AVAILABILITY;//指向metaclass
 3 
 4 #if !__OBJC2__
 5     Class super_class                                        OBJC2_UNAVAILABLE;//指向其父类
 6     const char *name                                         OBJC2_UNAVAILABLE;//类名
 7     long version                                             OBJC2_UNAVAILABLE;//版本号
 8     long info                                                OBJC2_UNAVAILABLE;//一些标识信息
 9     long instance_size                                       OBJC2_UNAVAILABLE;//该类的实例变量大小
10     struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;//用于存储每个成员变量的地址
11     struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;//方法列表
12     struct objc_cache *cache                                 OBJC2_UNAVAILABLE;//指向最近使用的方法的指针
13     struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;//存储该类遵守的协议
14 #endif
15 
16 } OBJC2_UNAVAILABLE;
17 /* Use `Class` instead of `struct objc_class *` */

 

下面我们看一下方法是如何调用的:

      首先,编译器将代码[obj start];转化为objc_msgSend(obj, @selector (start));,在objc_msgSend方法中。首先通过obj的isa指针找到obj对应的class。在Class中先去cache中 通过SEL查找对应方法method(猜测cache中method列表是以SEL为key通过hash表来存储的,这样能提高方法查找速度),若 cache中未找到。再去methodList中查找,若methodlist中未找到,则取superClass中查找。若能找到,则将method加 入到cache中,以方便下次查找,并通过method中的函数指针跳转到对应的方法中去执行。

posted on 2016-04-13 09:57  相而勿绝  阅读(234)  评论(0编辑  收藏  举报