文档章节

深入理解 runtime(运行时)机制—— 整理

BKF_
 BKF_
发布于 2016/03/07 14:19
字数 921
阅读 1010
收藏 5

runtime 就是系统在运行时的一些机制,其中最主要的是消息机制。
OC代码,最终都是转成了runtime(c语言库)的C语言实现。
eg:类转成了runtime库里面的结构体等数据类型
    方法转成了runtime库里面的C语言函数,平时调方法都是转成了objc_msgSend函数(所以说OC有个消息发送机制)

[Entity alloc] init]
objc_msgSend("Entity", "alloc")
objc_msgSend("Entity", "init")
objc_msgSend(objc_msgSend("Entity", "alloc"), "init")

runtime的多态:
对于C语言,编译完成之后函数的调用关系就已经确定。
OC的函数调用成为消息发送。属于动态调用过程。(在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错。)。只有在真正运行的时候才会根据函数的名称找 到对应的函数来调用。

[obj makeText];
objc_msgSend(obj,@selector(makeText));

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

@interface NSObject <nsobject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}</nsobject>
在NSObjcet中存在一个Class的isa指针。然后我们看看Class:
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; // 存储该类遵守的协议
}

iuqQFnm.png

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


本文转载自:

共有 人打赏支持
上一篇: 2.AFNetWorking
BKF_
粉丝 1
博文 21
码字总数 4291
作品 0
广州
私信 提问
iOS 模块详解—「Runtime面试、工作」看我就 🐒 了 ^_^.

iOS 模块详解—「Runtime面试、工作」看我就 🐒 了 ^_^. 转载:原地址https://www.jianshu.com/p/19f280afcb24 引导 对于从事 iOS 开发人员来说,所有的人都会答出「 Runtime 是运行时 」,...

法斗斗
2018/04/20
0
0
深入理解 nvidia-docker 2.0

女主宣言 上篇推送我们介绍了 nvidia-docker 2.0 在我司大规模 Kubernetes 集群上的实践,本篇文章就将介绍相较于旧版本,nvidia-docker 2.0 的设计优势及其实现机制,希望能对大家有所帮助。...

ZVAyIVqt0UFji
01/03
0
0
iOS 模块分解—「Runtime面试、工作」看我就 🐒 了 ^_^.

引导 相信对于从事开发人员来说 runtime 这个名称都不陌生,就像我起初只知道「 runtime 叫运行时 」,后来知道 runtime 同样可以像 KVC 一样访问私有成员变量,还有「 给类动态添加属性:L...

public-不知名开发者
2018/09/19
0
0
Runtime运行时机制

想深入理解Objective-C这门动态语言就不得不深入理解下它的“动态”是如何实现的。早先拜读过《Effective Objective-C 2.0》就让我更深入的窥探到OC运行时特别之处,本文当中也有部分内容借鉴...

Mister志伟
2017/12/11
0
0
《成神之路-高级篇》Java并发编程——锁

本文是《成神之路系列文章》的第一篇,主要是关于JVM的一些介绍。 持续更新中 数据库相关锁机制 数据库的锁机制 表级锁、行级锁、页级锁 共享锁、排他锁 乐观锁与悲观锁 乐观锁、悲观锁 乐观...

HollisChuang's Blog
2018/10/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

【大数据分析常用算法】9、马尔科夫模型

简介 这一章节我们讲解马尔科夫模型。给定一组随机变量(如顾客最近的交易日期),马尔科夫模型只根据前一个状态(前一个最近交易日期)的分部指示该变量最近的分布。 1、马尔科夫链基本原理...

Areya
22分钟前
0
0
vue自定义属性

vue自定义属性如果是固定的非写死的,可以直接写,例如 <button vkshop-event-name="buyNow" vkshop-event-type="click"></button> 如果是动态属性,需要加冒号 : <button :vkshop-event-na......

litCabbage
25分钟前
0
0
Java 线程池的使用好处

使用线程池的好处: 1.减少在创建和销毁线程上所花的时间以及系统资源的开销 2.如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存 以下是Java自带的几种线程池: 1、newFixedT...

飓风2000
29分钟前
0
0
Ubuntu 16.04安装Java 8

1 Java 8 下载地址 http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk8-downloads-2133151-zhs.html 2 以root用户登录将下载的jdk-8u92-linux-x64.tar.gz文件放到/temp目录下......

群星纪元
39分钟前
1
0
我们总结了每个技术团队都会遇到的 4 个难题

阿里巴巴 2019 年实习生校园招聘已经启动,为此,我们整理了一篇《每个技术团队都会遇到的4个难题》,帮助即将从校园进入公司实习的后端程序员,以实践的视角,看看一个后端技术团队会遇到的...

阿里云云栖社区
43分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部