iOS runtime的简单理解

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

Objective-C Runtime 是什么?

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

(上段引用自:http://www.cocoachina.com/iOS/20141008/9844.html)

之前对于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  成员变量的数组

 

  1. struct objc_ivar_list {
  2. int ivar_count;
  3. /* variable length structure */
  4. struct objc_ivar ivar_list[1];
  5. }
methodLists  方法定义的数组
  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   指向最近使用的方法.用于方法调用的优化.
  1. struct objc_cache {
  2. unsigned int mask /* total = mask + 1 */;
  3. unsigned int occupied;
  4. Method buckets[1];
  5. };
protocols 协议的数组
  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里方便下次的查找.

以上就是我对运行时的消息发送机制的了解,现在了解的还是比较浅,不够深入,等以后进一步学习的时候,会将更多的内容分享出来.下一篇文章将会介绍runtime在开发中经常用到的地方.

时间: 2024-08-28 20:27:20

iOS runtime的简单理解的相关文章

iOS 多线程的简单理解(3)执行方式 + 执行对列 的组合

通过对前面两偏线程理解的总结,自己对线程的理解也逐渐加深,梳理的清晰起来-- 通常在使用线程 的时候,都是要用到 执行对列,执行方式,执行任务, 现在开始新一轮的深入 3. 1. 1  同步 + 串行 - (void)syncSerialQueue{ dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL); NSLog(@" 同步 + 串行 start:::%@ ",

iOS runtime实战应用:关联对象

在开始之前建议先阅读iOS runtime的基础理解篇:iOS内功篇:runtime 有筒子在面试的时候,遇到这样一个问题:"如何給NSArray添加一个属性(不能使用继承)",筒子立马蒙逼了,不能用继承,难道用分类?但是分类貌似只能添加方法不能添加属性啊,筒子百思不得其解,直到后来接触到了runtime才恍然大悟. 什么是关联对象 关联对象是指某个OC对象通过一个唯一的key连接到一个类的实例上.举个例子:xiaoming是Person类的一个实例,他的dog(一个OC对象)通过一根

iOS runtime探究(三): 从runtime开始理解OC的属性property

你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639303 本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向: 从runtime开始: 理解面向对象的类到面向过程的结构体 从runtime开始: 深入理解OC消息转发机制 从runtime开始: 理解OC的属性property 从runtime开始: 实践Category添加属

iOS runtime探究(二): 从runtime開始深入理解OC消息转发机制

你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639289 本文主要解说runtime相关知识,从原理到实践.由于包括内容过多分为下面五篇文章详细解说.可自行选择须要了解的方向: 从runtime開始: 理解面向对象的类到面向过程的结构体 从runtime開始: 深入理解OC消息转发机制 从runtime開始: 理解OC的属性property 从runtime開始: 实践Category加入属

iOS runtime探究(一): 从runtime开始理解面向对象的类到面向过程的结构体

你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639205 本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向: 从runtime开始: 理解面向对象的类到面向过程的结构体 从runtime开始: 深入理解OC消息转发机制 从runtime开始: 理解OC的属性property 从runtime开始: 实践Category添加属

iOS runtime探究(四): 从runtiem开始实践Category添加属性与黑魔法method swizzling

你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639335 本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向: 从runtime开始: 理解面向对象的类到面向过程的结构体 从runtime开始: 深入理解OC消息转发机制 从runtime开始: 理解OC的属性property 从runtime开始: 实践Category添加属

iOS runtime探究(五): 从runtime开始深入weak实现机理

你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639341 本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向: 从runtime开始: 理解面向对象的类到面向过程的结构体 从runtime开始: 深入理解OC消息转发机制 从runtime开始: 理解OC的属性property 从runtime开始: 实践Category添加属

iOS沙盒简单介绍

先简单介绍一下什么是沙盒:你可以简单理解成为一个目录,这个目录的改动不会对操作系统造成任何损失.(这里也有一点点介绍) 看看苹果的沙盒目录: 再附一张苹果官方的图 一个iOS app操作都是在自己的沙盒中进行的. 首先: Deveices,里面是各种的模拟器设备. 然后随便找一个模拟器设备.里面的data是里面的数据.然后Container里面Data中有一个Application就是该设备的安装软件. 我们可以看到里面有好多个(就算我们Reset Content and Settings,也会

php类的封装、继承和多态的简单理解

.面象对向的三大特点:封装性.继承性.多态性 首先简单理解一下抽象: 我们在前面定义一个类的时候,实际上就是把一类事物共有的属性和行为提取出来,形成一个物理模型(模版),这种研究问题的方法称为抽象 一.封装性  封装就是把抽取出来的数据和对数据的操作封装在一起,数据被保护在内部,程序的其他部分只有被授权的操作(方法)才能对数据进行操作.  php提供了三种访问控制修饰符  public 表示全局,本类内部,类外部,子类都可以访问  protected 表示受保护的,只有本类或子类可以访问  pr