iOS面试--Runtime(动态运行时)

前言

2020年已经注定了:新型冠状病毒肆虐,追了 15 年的偶像Kobe与世长辞,禽流感来袭等等。这是多灾多难的一年! 太多的坏事情坏消息消耗了人们太多的热情和信心,我们只能将一切寄予希望,即使是很空虚的希望;我们憧憬新型冠状病毒的离开,生活重归于好,我们期待时间能够治愈科比离世带给我们的痛苦,所有的这些坏事情坏消息仅仅是一个开始,它们还没有开足马力,由于惯性,还会横冲直撞一段时间和路程。 过苦日子的悲惨现实,已经支撑不起伟大、强大和辉煌的梦想。所以我们只能寄希望于未来,而为了我们的未来,所以还是要继续前行!!!
Dear thoughts are in my mind, and my soul it soars enchanted.

矫情之后,还是要回归正题。关于 Runtime 的面试,我们主要从下面几个问题出发。

  • 编译时语言和 Objective-C 这种动态运行时语言有何区别?
  • 消息传递和函数调用有什么不同?
  • 当我们调用一个方法没有实现时,系统是如何为我们转发?
  • 当我们在消息传递的过程中,如何进行方法缓存的查找?

Runtime

runtime 概述

runtime 我们主要是从以下八个模块去分析,数据结构、类对象与元类对象、消息传递、方法缓存、方法转发、Method-Swizzling、动态添加方法以及动态方法解析,如下图所示


runtime 数据结构

objc_object

objc_object 其实就是 id,每一个 objc_object 中均有一个 isa 指针

objc_object 数据结构
  • isa_t 指针
  • 关于 isa 操作
  • 弱引用相关
  • 关联对象相关方法
  • 内存管理相关方法


    id 内部结构体
Class == objc_class
objc_class
  • isa 指针
  • 共用体 isa_t


    isa 指针

    其实在 32 位架构的机器上,那么 isa 指针的位数就是 32 位,64 位机器则为 64 位。如图所示以 64 位为例,isa指针包括指针型 isa 指针和非指针型 isa 指针,指针型的 isa 的值代表的就是 class 的地址,对于非指针型的 isa,那么 isa 的部分值代表 class 的地址,为什么会这样设计,因为有时候 class 的地址的长度不需要那么长,那么多余的位数可以用来存储其他的值。

isa 指向

  • 关于对象的 isa 指针,其指向的是类对象
  • 对于实例对象来说(id),isa 指针指向的是其 Class 对象;
  • 关于类对象(Class),其 isa 指针指向的是其元类对象(meta_class)
cache_t

主要用于提高方法调用的速度或者消息传递的速度

  • 用于\color{red}{快速查找}方法执行函数
  • 是一个\color{red}{可增量扩展}的哈希表结构 (用哈希主要是提高查找效率)
  • \color{red}{局部性原理}的最佳应用
    局部性原理:把调用方法频率最高的放到缓存中以提高命中率
    cache_t 数据结构

class_data_bits_t

  • class_data_bits_t 主要是对 class_rw_t 的封装
  • class_rw_t 代表的是类相关的读写信息、对 class_ro_t 的封装
  • class_ro_t 代表的是类的只读信息

class_rw_t

class_rw_t 的数据结构
class_rw_t 原理解析

https://www.jianshu.com/p/585845127007

class_ro_t

class_ro_t 数据结构

method_t

函数四要素:函数的名称、函数的返回值、函数的参数、函数体


method_t 数据结构

如上图所示

  • name:方法的名称
  • types:函数的返回值和参数的组合
  • imp: 无类型的函数指针,指向的就是函数体

\color{red}{types 是如何表述函数的返回值和参数?}

Type Encodings
runtime 数据结构表

对象、类对象、元类对象

  • 类对象存储实例方法列表等信息
  • 元类对象存储类对象的方法列表等信息
对象、类对象、元类对象之间的关系图

如上图所示,实例对象可以通过 isa 指针找到其类对象,而类对象可以通过 isa 指针找到他的元类对象;同时类对象可以通过 superclass 指针找到它的 Superclass 对象一直到 Rootclass,元类对象也是如此;类对象和元类对象因为继承自 NSObject, 所以他们中也有 isa 指针,对于每一个元类对象的 isa 指针都指向根元类对象;根元类对象的 superclass指针指向的是根类对象

消息传递

消息传递流程图

缓存查找

类对象查找(已排序的列表采用二分查找、未排序的使用一般遍历)
元类对象查找(父类逐级遍历)

消息转发流程

消息转发流程

https://www.jianshu.com/p/ba0e9942a082

Method Swizzling

动态添加一个方法?

当面试官问你@dynamic关键字的时候,如何回答?

  • 动态运行时语言将函数的决议推迟到运行时
  • 编译时语言在编译期间进行函数的决议

runtime 实际面试问题

1. [obj foo] 和 objc_msgsend()函数之间有什么关系?
 objc_msgSend()是[obj foo]的具体实现。
 在runtime中,objc_msgSend()是一个c函数,[obj foo]会被翻译成这样的形式objc_msgSend(obj, foo)。
系统会先去obj的对应的类中找方法;
再进行缓存,找不到再去找方法列表;
再找父类,如此逐级向上传递;
最后再找不到就要转发。
2. runtime 如何通过Selector 找到对应的 IMP 地址的?(考察消息传递机制)
对于实例方法,每个实例的 isa 指针指向着对应类对象,
而每一个类对象中都一个对象方法列表。
对于类方法,每个类对象的 isa 指针都指向着对应的元对象,
而每一个元对象中都有一个类方法列表。
方法列表中记录着方法的名称,方法实现,以及参数类型,
其实 selector 本质就是方法名称,通过这个方法名称就可以在方法列表中找到对应的方法实现。
Selector、Method 和 IMP 的关系可以这样描述:在运行时分发消息,方法列表中的每一个实体都是一个方法(Method),
它的名字叫做选择器(SEL),对应着一种方法实现(IMP)。
3. 能否向编译后的类中添加实例变量?
4. 能否向运行时动态创建的类中添加实例变量?为什么?
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,997评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,603评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,359评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,309评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,346评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,258评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,122评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,970评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,403评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,596评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,769评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,464评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,075评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,705评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,848评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,831评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,678评论 2 354

推荐阅读更多精彩内容