Runtime在面试中是经常问到的一个问题,究竟什么是Runtime呢?Runtime简称运行时,就是系统在运行时的一些机制,其中最主要的是消息机制,对于C语言,函数的调用在编译的时候会决定调用哪个函数。编译完成之后直接顺序执行。OC的函数调用成消息发送,属于动态调用过程,在编译的时候并不能真正决定调用哪个函数(实际上在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明就不会报错,而C语言就会报错)。只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。

OC的实现动态如何调用呢?下面举了一个小例子。

1 [obj makeText];

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

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

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

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

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

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

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中的函数指针跳转到对应的函数中去执行。

转载于:https://www.cnblogs.com/520gp-iOS/p/4853913.html

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. Runtime底层原理总结--反汇编分析消息转发

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

  3. Objective-C Runtime的数据类型

    转自:http://www.cnblogs.com/whyandinside/archive/2013/02/26/2933552.html Class Objective-C是支持反射的,先来了解一 ...

  4. Objective-C中的消息发送总结

    关于OC中的消息发送的实现,在去年也看过一次,当时有点不太理解,但是今年再看却很容易理解. 我想这跟知识体系的构建有关,如果你不认识有砖.水泥等这些建筑的基本组成部分,那么我们应该很难理解建筑是怎么建 ...

  5. 转:Object-Runtime的基本数据类型

    Class Objective-C是支持反射的,先来了解一下其如何表达一个类.在Objective-C的Runtime中有个类型是Class(只在Runtime环境中使用),用来表示Objective ...

  6. iOS逆向之深入解析如何Hook所有+load方法及Category的处理

    一.类方法 +load iOS 有四种方法可方便的在 premain 阶段执行代码: Objective C 类的 +load 方法: C++ static initializer: C/C++ at ...

  7. xcode扩展_如何将Xcode插件转换为Xcode扩展名

    xcode扩展 by Khoa Pham 通过Khoa Pham 如何将Xcode插件转换为Xcode扩展名 (How to convert your Xcode plugins to Xcode e ...

  8. iOS 面试基础题目

    转载: iOS 面试基础题目 题目来自博客:面试百度的记录,有些问题我能回答一下,不能回答的或有更好的回答我放个相关链接供参考. 1面 Objective C runtime library:Obje ...

  9. 深入理解iOS App的启动过程

    前言 启动时间是衡量应用品质的重要指标. 本文首先会从原理上出发,讲解iOS系统是如何启动App的,然后从main函数之前和main函数之后两个角度去分析如何优化启动时间. 准备知识 Mach-O 哪 ...

  10. 深入理解iOS APP启动过程

    前言 启动时间是衡量应用品质的重要指标. 本文首先会从原理上出发,讲解iOS系统是如何启动App的,然后从main函数之前和main函数之后两个角度去分析如何优化启动时间. 准备知识 Mach-O 哪 ...

最新文章

  1. docker 退出mysql_Docker mysql即时退出
  2. 跨链(2)跨链技术“哈希锁定(Hash-locking)”
  3. POJ 3069 Saruman's Army(贪心)
  4. 如何取消IE窗口的全屏显示
  5. 第十二期:常用的几种大数据架构剖析
  6. oracle批量把小写转换成大写,oracle数据库批量将表名小写转大写
  7. 一步一步写算法(之n!中末尾零的个数统计)
  8. bada 2D游戏编程之八——逐帧动画
  9. steam社区、好友列表无法打开问题通解
  10. 梦想CAD控件 2021.12.06更新,网页浏览编辑CAD,CAD插件
  11. 全面解释java中StringBuilder、StringBuffer、String类之间的关系
  12. [置顶]使用scrapy_redis,自动实时增量更新东方头条网全站新闻
  13. 瑞科生物港交所上市:市值121亿港元 9个月期内亏损5.2亿
  14. 苏嵌//张福辉//2018.7.11
  15. R语言 如何绘制文章的词云图——从分词到绘图(it-idf权重)
  16. 控制类(Controller)
  17. poj 2942 Knights of the Round Table(双连通分量+tarjan+二分图判定)
  18. 2019年9月8日秋季PAT甲级题解A1163(7-4)Dijkstra Sequence
  19. 什么是AJAX?如何实现AJAX异步请求?
  20. 多进程写同一个日志并发问题分析

热门文章

  1. Linux下安装Mysql详解
  2. Kattis - missinggnomesD Missing Gnomes (思路题)
  3. 从jsp页面到servlet传值的不同方式
  4. C/C++深度分析(二)
  5. 加锁解锁PHP实现 -转载
  6. iOS 8 Auto Layout界面自动布局系列5-自身内容尺寸约束、修改约束、布局动画
  7. 分享Silverlight/WPF/Windows Phone一周学习导读(10月22日-10月29日)
  8. k8s Custom Resource
  9. Java语法基础学习DayTwo
  10. Java 基础系列-LocalDate相关