最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题。当然还有一些其他问题也几乎必问,例 如:RunLoop,Block,内存管理等。其他的问题如果有机会我会在其他文章中介绍。本篇文章主要介绍RunTime。

RunTime简称运行时。就是系统在运行的时候的一些机制,其中最主要的是消息机制。对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 )。编译完成之后直接顺序执行,无任何二义性。OC的函数调用成为消息发送。属于动态调用过程。在编译的时候并不能决定真正调用哪个函数(事实证明,在编 译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错。而C语言在编译阶段就会报错)。只有在真正运行的时候才会根据函数的名称找 到对应的函数来调用。

那OC是怎么实现动态调用的呢?下面我们来看看OC通过发送消息来达到动态调用的秘密。假如在OC中写了这样的一个代码:

1
[obj makeText];

其中obj是一个对象,makeText是一个函数名称。对于这样一个简单的调用。在编译时RunTime会将上述代码转化成

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

首先我们来看看obj这个对象,iOS中的obj都继承于NSObject。

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

在NSObjcet中存在一个Class的isa指针。然后我们看看Class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef struct objc_class *Class;
struct objc_class {
  Class isa; // 指向metaclass
   
  Class super_class ; // 指向其父类
  const char *name ; // 类名
  long version ; // 类的版本信息,初始化默认为0,可以通过runtime函数class_setVersion和class_getVersion进行修改、读取
  long info; // 一些标识信息,如CLS_CLASS (0x1L) 表示该类为普通 class ,其中包含对象方法和成员变量;CLS_META (0x2L) 表示该类为 metaclass,其中包含类方法;
  long instance_size ; // 该类的实例变量大小(包括从父类继承下来的实例变量);
  struct objc_ivar_list *ivars; // 用于存储每个成员变量的地址
  struct objc_method_list **methodLists ; // 与 info 的一些标志位有关,如CLS_CLASS (0x1L),则存储对象方法,如CLS_META (0x2L),则存储类方法;
  struct objc_cache *cache; // 指向最近使用的方法的指针,用于提升效率;
  struct objc_protocol_list *protocols; // 存储该类遵守的协议
    }

我们可以看到,对于一个Class类中,存在很多东西,下面我来一一解释一下:

Class isa:指向metaclass,也就是静态的Class。一般一个Obj对象中的isa会指向普通的Class,这个Class中存储普通成员变量和对 象方法(“-”开头的方法),普通Class中的isa指针指向静态Class,静态Class中存储static类型成员变量和类方法(“+”开头的方 法)。

Class super_class:指向父类,如果这个类是根类,则为NULL。

下面一张图片很好的描述了类和对象的继承关系:

注意:所有metaclass中isa指针都指向跟metaclass。而跟metaclass则指向自身。Root metaclass是通过继承Root class产生的。与root class结构体成员一致,也就是前面提到的结构。不同的是Root metaclass的isa指针指向自身。

Class类中其他的成员这里就先不做过多解释了,下面我们来看看:

@selector (makeText):这是一个SEL方法选择器。SEL其主要作用是快速的通过方法名字(makeText)查找到对应方法的函数指针,然后调用其函 数。SEL其本身是一个Int类型的一个地址,地址中存放着方法的名字。对于一个类中。每一个方法对应着一个SEL。所以iOS类中不能存在2个名称相同 的方法,即使参数类型不同,因为SEL是根据方法名字生成的,相同的方法名称只能对应一个SEL。

下面我们就来看看具体消息发送之后是怎么来动态查找对应的方法的。

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

Objective-C总Runtime的那点事儿(一)消息机制相关推荐

  1. 刨根问底Objective-C Runtime(2)- Object Class Meta Class

    刨根问底Objective-C Runtime(2)- Object & Class & Meta Class Chun Tips 专注iOS开发 刨根问底Objective-C Ru ...

  2. 刨根问底Objective-C Runtime

    该笔记分为四篇: 刨根问底Objective-C Runtime(1)- Self & Super 刨根问底Objective-C Runtime(2)- Object & Class ...

  3. 刨根问底Objective-C Runtime(1)- Self Super

    转:http://chun.tips/blog/2014/11/05/bao-gen-wen-di-objective%5Bnil%5Dc-runtime(1)%5Bnil%5D-self-and-s ...

  4. NSObject头文件解析 / 消息机制 / Runtime解读 (一)

    NSObject头文件解析 当我们需要自定义类都会创建一个NSObject子类, 比如: #import <Foundation/Foundation.h>@interface Class ...

  5. Runtime底层原理总结--反汇编分析消息转发

    消息转发:发送一个消息,也就是sel查找imp,当没有找到imp,接下来进入动态方法解析,如果开发者并没有处理,会进入消息转发. 消息转发 前几篇文章介绍了Runtime底层原理和动态方法解析总结 , ...

  6. 【转载】Objective-C runtime 消息机制

    在Objective-C中,message与方法的真正实现是在执行阶段绑定的,而非编译阶段.编译器会将消息发送转换成对objc_msgSend方法的调用. objc_msgSend方法含两个必要参数: ...

  7. 安卓 Handler 消息机制(总)

    注:本文参考于某公开课,如有侵权,请联系本人,会立即删除 注:仅用作自我学习记录,未有任何商业用途. 关于handler的由来 开始前的闲言碎语 我们都知道handler是安卓的消息传递机制,使用ha ...

  8. Objective C运行时(runtime)技术总结,好强大的runtime

    前言:          Objective C的runtime技术功能非常强大,能够在运行时获取并修改类的各种信息,包括获取方法列表.属性列表.变量列表,修改方法.属性,增加方法,属性等等,本文对相 ...

  9. RunTime技术总结

    前言:          Objective C的runtime技术功能非常强大,能够在运行时获取并修改类的各种信息,包括获取方法列表.属性列表.变量列表,修改方法.属性,增加方法,属性等等,本文对相 ...

最新文章

  1. 微信朋友圈装x代码_NBA总决赛朋友圈装X图鉴:直男之间有真正的友谊吗?
  2. (一)MVC5干货篇,目录和路由
  3. tensorflow详解-tf.nn.conv2d(),tf.nn.max_pool()
  4. 排查指南 | 两个案例学会从埋点排查 iOS 离线包
  5. Mac OS X 显示和隐藏文件
  6. python购物信息整合教程_python实现简单购物商城
  7. 零基础web前端和python哪个好学一些?
  8. 使用C#进行点对点通讯和文件传输(通讯基类部分+发送接收
  9. 鸿蒙 自研内核 core b,华为平板将首次搭载鸿蒙OS 2.0系统:首次自研内核与构架...
  10. POI实现超大数据的Excel的读写操作
  11. Orcad CIS本地库添加器件
  12. 为胎儿诵地藏经的好处(合集)怀孕的一定要看哦!
  13. java 余弦值_获取Java中给定值的双曲余弦值
  14. 2021年最新独立版橙色去水印微信小程序-更新2021.8.31
  15. bitcoin找零机制
  16. 基于微信小程序的毕业设计题目(34)PHP小说平台小程序(含开题报告、任务书、中期报告、答辩PPT、论文模板)
  17. BT之家种子连接提取
  18. 在线直播|是事实还是贩卖焦虑?IT行业也偏爱“小鲜肉”
  19. PDFBOX将PDF转图片(PNG背景透明)
  20. Redis - 附近商铺

热门文章

  1. 在几何画板中如何制作圆柱的侧面展开动画_倒计时与时钟演示 | 几何画板
  2. Luban(鲁班)——可能是最接近微信朋友圈的图片压缩算法
  3. 【小白学习PyTorch教程】十五、BERT:通过PyTorch来创建一个文本分类的Bert模型
  4. 人工智能时代背景下,NLP方向或将悄悄崛起
  5. 独家定制「炼丹贴纸」免费送,让你成为实验室最靓的仔
  6. 首次统一卷积与自注意力,X-volution发力网络核心基础架构创新
  7. ​Transformer升级之路:从Performer到线性Attention
  8. 3D Human相关研究总结:人体、姿态估计、人体重建等
  9. 最后9个名额丨知识图谱理论与实战(线下集训)
  10. AI 玩微信跳一跳的正确姿势:跳一跳 Auto-Jump 算法详解