美文网首页iOS知识点
iOS-RunTime相关知识点整理

iOS-RunTime相关知识点整理

作者: 木子奕 | 来源:发表于2019-01-21 23:33 被阅读0次

Runtime.png
  • 类对象与元类对象的区别?

  • [obj foo] 和 objc_msgSend 函数有什么关系?

  • runtime 如何通过 Selector 找到对应的IMP地址的? (消息传递过程)


Runtime 内容汇总

904629-3ab2a221da9dae6b.png

这节的讲解内容

  • Runtime 数据结构

  • 类对象与元类对象 & 消息传递

  • 消息转发


数据结构

image.png image.png image.png

cache_t存储的是类的缓存快速查找的hash表

image.png image.png

class_rw_t主要存储的是和分类相关的内容

image.png

class_ro_t主要存储的是和原始类相关的内容

image.png

method_t的结构体与函数的对应关系如下所示

image.png

方法的Type Encondings

image.png

类的整体存储结构

904629-82cd4639a024707a.png

上图可以看出 Runtime 整体的数据结构

  • superClass 指向当前类的父类

  • cache_t 提供消息传递过程当中的缓存方法查找 , 实质上是装满了 bucket_t 的一个 hash 表

  • class_data_bits_t 类的基础信息,包含了类的方法列表,协议列表等。


类对象与元类对象 & 消息传递

类对象与元类对象
  • 类对象存储实例方法列表等信息

  • 元类对象存储类方法列表等信息

看一个官方很经典的图

904629-b0909bd8eaa595a0.png

objc_class 继承于 objc_object,也就是说一个 ObjC 类本身同时也是一个对象,为了处理类和对象的关系,runtime库创建了一种叫做元类 (Meta Class)的东西,类对象所属类型就叫做元类,它用来表述类对象本身所具备的元数据。类方法就定义于此处,因为这些方法可以理解成类对象的实例方法。每个类仅有一个类对象,而每个类对象仅有一个与之相关的元类。当你发出一个类似[NSObject alloc] 的消息时,你事实上是把这个消息发给了一个类对象 (Class Object),这个类对象必须是一个元类的实例,而这个元类同时也是一个根元类 (root meta class)的实例。所有的元类最终都指向根元类为其超类。所有的元类的方法列表都有能够响应消息的类方法。所以当 [NSObject alloc]这条消息发给类对象的时候,objc_msgSend() 会去它的元类里面去查找能够响应消息的方法,如果找到了,然后对这个类对象执行方法调用。

上图实线是 superclass 指针,虚线是isa指针。 有趣的是根元类的超类是 NSObject,而 isa 指向了自己,而 NSObject 的超类为nil,也就是它没有超类。

这里讲的非常详细了

消息传递
904629-6914043db2c075c2.png

这就是消息传递的一个流程,首先查缓存,无缓存,查方法列表,依然没命中,再顺次查找各个父类方法列表,如果都没有名字,就转到消息转发流程

如果问具体在缓存和方法列表查找过程中的内部情况,可以简单的这样答一下

  • 在缓存查找阶段是 哈希查找

  • 当前类方法查找 , 如果是已排序的列表,就采用二分查找,没排序的采用一般遍历

  • 逐级父类方法查找 ,是根据 superClass 指针逐级遍历每一个父类

看一个经典的面试题
904629-0f9525b131902843.png

结果是都打印出来 phone

为什么呢?先看一下 [self class][super class]的消息传递

904629-40e52989b6b43445.png 904629-05f1dff5c55559df.png

这里可以看到 objc_super 结构体当中 receiver 就是当前对象 。 也就是说 无论是 [self class]或者 [superclass] ,接收者都是当前对象!!

继续, 我们对应着官方流程图(图三)来解答一下

当前的实例是 phone [self class] -->objc_msgSend(self,@selector(class)), 首先通过实例的 isa 指针找到 phone的类对象,它本身是没有 class 方法的,然后往父类找,也没有。 顺次一直查找到根类也就是 NSObject ,将class的具体实现返回给调用方,也就是 phone

instance of Subclass --> Subclass(class) -->Superclass(class)-->Root class(class)

[super class] -->objc_msgSendSuper(self,@selector(class))。 接受者依然是当前的 phone这个实例,区别不同的是 它会从父类的方法了列表开始查找,也就是

instance of Subclass --> Superclass(class)-->Root class(class)

所以依然还是 phone;

方法的查找过程

image.png image.png

消息转发

904629-43edc5597d2c72ea.png

实践出真知,跑一下demo


@dynamic getter和setter 在运行时生成

image.png

相关文章

  • iOS-RunTime相关知识点整理

    类对象与元类对象的区别? [obj foo] 和 objc_msgSend 函数有什么关系? runtime 如何...

  • iOS-runtime相关

    本篇涵盖runtime的解析、应用等. 1.runtime快速入门和实战2.Runtime 10种用法(没有比这更...

  • 壹、面试复习OC篇之runtime

    暂时copy过来,过后添加自己理解 原文地址:iOS-runtime通篇详解-上 iOS-runtime通篇详解-...

  • GO语言

    map相关操作整理 知识点整理: 创建 make(map[string]string) 获取元素 m[key] k...

  • Looper相关知识点整理

    1.Looper是什么? Looper在线程间通信中扮演消息循环的角色,不停的从MessageQueen中查看是否...

  • PM相关知识点整理

    以下为学习产品相关的知识点,知识点比较杂乱,先记录下来 PM- 分析师,设计师,沟通桥梁,产品缔造者 特点- 易于...

  • Java线程并发小例子的思考,寻求大佬答疑解惑

    我在整理Java并发相关知识点的时候,准备写个多线程不安全的例子来放在博客里面,由例子引出相关知识点来帮助自己理解...

  • iOS开发 runtime理解

    http://yimouleng.com/2015/05/28/ios-runtime/

  • iOS知识梳理:RunLoop

    相关连接:深入理解RunLoopIOS---实例化讲解RunLoopiOS知识点整理-RunLoopRunLoop...

  • iOS知识点整理

    iOS知识点整理 持续更新中。。。 runtime相关 iOS 模块详解—「Runtime面试、工作」看我就 ? ...

网友评论

    本文标题:iOS-RunTime相关知识点整理

    本文链接:https://www.haomeiwen.com/subject/rtnhjqtx.html