runtime的简单理解

        最近闲了下来,有时间了就研究一下runtime的运行机制,之前做开发的时候一直也没有特别关注这个东西,只是知道有,但是很少去刻意的使用,研究的不是很深,简单说一下吧,有错误的地方欢迎大家随时指正.

Objective-C Runtime 是什么?

Objective-C 的 Runtime 是一个运行时库(Runtime Library),它是一个主要使用 C 和汇编写的库,为 C 添加了面相对象的能力并创造了 Objective-C。这就是说它在类信息(Class information) 中被加载,完成所有的方法分发,方法转发,等等。Objective-C runtime 创建了所有需要的结构体,让 Objective-C 的面向对象编程变为可能.

        之前对于runtime的理解,只是仅仅局限于对变量或者对象的类型由编译时推迟到了运行时.比如定义一个NSString类型的变量,语句这么写

         则会输出


        很明显,当我们定义了NSSring类型的变量str之后,其类型并没有确定下来,而是等到运行的时候,才确定了对象的类型.

       但是这并不是今天要说的重点,如果运行时只有这点功能的话,那么苹果的工程师也就太大材小用了,运行时最重要的作用还是体现在消息机制上.

       我们都知道,OC是一门面向对象的语言,很多时候在解决问题的时候都是站在面向对象的角度来考虑.比如我要造一座房子,我并不需要考虑如何去建设,只需要考虑把这个任务分给几个人去做,比如A制作窗户,B制作门,C制作屋顶….我只需要考虑把这些任务分配给几个人去做,至于他们是怎么实现的我并不需要考虑.就拿给A分配任务来说,调用下面的方法:


      这样就把任务分配给了A,那么在运行时编译后的语句则如下所示

                 objc_msgSend(aPeple,@selector(makeWindow));


      将[aPeople makeWindow]转化为了objc_msgSend函数的格式,这个函数有两个参数,第一个参数就是我们创建的对象,第二个参数是一个方法选择器,使用@selector(makeWindow)来生成一个SEL,SEL就是对方法的一种包装。包装的SEL类型数据它对应相应的方法地址,找到方法地址就可以调用方法.接着根据SEL去aPeople归属的class里去查找,我们先看一下OC中class的结构,其实Class就是一个指向结构体的指针,其内容如下:


以下是对参数的具体详解,其代码部分来自runtime的源代码,引自:http://blog.csdn.net/uxyheaven/article/details/38113901

version  类的版本信息,默认为0
info  供运行期使用的一些位标识。
instance_size  该类的实例变量大小
ivars  成员变量的数组
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. struct objc_ivar_list {  
  2.     int ivar_count;  
  3.     /* variable length structure */  
  4.     struct objc_ivar ivar_list[1];  
  5. }  
methodLists  方法定义的数组
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. struct objc_method_list {  
  2.     struct objc_method_list *obsolete;  
  3.     int method_count;  
  4.     /* variable length structure */  
  5.     struct objc_method method_list[1];  
  6. }  
objc_cache   指向最近使用的方法.用于方法调用的优化.
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. struct objc_cache {  
  2.     unsigned int mask /* total = mask + 1 */;  
  3.     unsigned int occupied;  
  4.     Method buckets[1];  
  5. };  
protocols 协议的数组
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. struct objc_protocol_list {  
  2.     struct objc_protocol_list *next;  
  3.     long count;  
  4.     Protocol *list[1];  
  5. };  

      调用objc_msgSend函数的时候,首先会使用@selector(makeWindow)产生的SEL去class的cache里去查找函数的指针,如果在这里找到的话,则直接调用;如果没有找到的话,则去methodList里查找函数的指针,找到的话直接调用,没有找到的话再去super_class里查找,找到后将该函数指针缓存到cache里方便下次的查找.





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值