iOS runtime总结数据结构,消息传递、转发和应用场景

runtime篇

首先看一下runtiem底层的数据结构


首先从objc_class这么一个结构体(数据结构)开始,objc_class继承于objc_object。

objc_object当中有一个成员变量叫isa_t,那么这个isa_t指针就指向一个objc_class类型的类对象(或者说元类对象)。

objc_class主要包含三个成员变量,superClass(指向当前类的父类)、cache_t(用来提供消息传递过程中的缓存方法查找)、class_data_bits_t(类的一些基本信息:类所定义/通过分类所添加 的成员变量,属性,方法列表都在这个数据结构中)

superClass:实际是class类型的,它指向objc_class类型的这样一个指针

cache_t:实际上是装满了bucket_t数据结构的Hash表,维护的也就是这个hash表

class_data_bits_t:实际上是对class_rw_t的数据结构的封装class_rw_t中包含了(class_ro_t类相关的只读信息、protocols类分类中的协议、properties类分类中的属性、methods类分类中的方法)

class_ro_t包含了name类名、methodList类的方法列表--method_t、ivars声明的类的成员变量、类的属性、类的协议。

Runtime基础数据结构如下: objc_object、objc_class、isa指针、method_t

下面讲一下runtime的根元类

objc_object

即id类型(我们平时用的所有对象都是id类型的,在runtime中,id 就是 objc_object结构体)


objc_object结构体主要包含:

1.isa_t:共用体。

2.关于isa操作相关的一些方法:通过objc_object结构体,来获取isa所指向的类对象,或者通过类对象的isa指针获取它的元类对象一些遍历的放大。

3.弱引用相关:标记一个对象是否曾经有过弱引用指针。

4.关联对象相关方法:我们为对象设置了关联属性,关于关联属性的一些相关方法也体现在objc_object结构体中。

5.内存管理相关的方法实现:MRC下经常用到的runtain,release等方法实现 ,以上均封装在objc_object结构体中

objc_class

OC中的Class,代表一个类,他在runtime中对应objc_class的数据结构(结构体)。

objc_class继承objc_object

所以Class这样一个类也是一个对象,称为类对象,因为它继承自objc_object。


objc_class包含:

1.objc_class拥有一个superClass指针,指向class类型,(如果说Class是一个类对应的话,superClass指针指向的就是它的父类对象,就是我们平时说的类与父类,实际上是通过objc_class中superClass成员变量来定义的)。

2.cache_t cache成员变量: 方法缓存结构,消息传递时会使用这样的数据结构。

3.class_data_bits_t bits数据结构: 关于类所定义的变量,属性,方法都在bits这样一个成员结构中。

isa指针

它是C++中的共用体,在OC中名称是isa_t

不论是64位架构上(或者32位架构)上面,共用体是64个(或者32个) 0或者1的数字 (按大多数64位分析)


分两种类型(isa指针是什么含义的时候):

1.指针型isa: 64位的0或者1的整体内容代表所指向的Class的地址,也就是可以通过isa的内容来获得类对象的地址。

2.非指针型isa: isa的值得部分代表Class的地址,之所以这样是因为我们在寻址过程中,只有三四十位数就可以保证我们寻找到所有Class地址了,多出来的位可以用来存储其他相关内容,来达到节省内存的目的。

isa的指向:


关于对象,它指向类对象

例如我们拥有一个实例,实例就是OC中对应的id类型,在Runtime中就是objc_object,里面有个isa指针,会指向它对应的Class。

关于类对象,指向元类对象

class因为集成objc_object,所以里面也有isa指针,指向其元类对象。

当我们进行方法调用时,调用一个实例的实例方法,实际上是通过isa指针,到它的类对象中,去进行方法查找。

如果我们调用的是类方法,那么是通过类对象的isa指针,到它的元类对象中去查找。

cache_t

是用于快速查找方法执行函数的一个结构(当我们调用一个方法时,如果有缓存,我们就不需要去方法列表中遍历了,可以提高方法调用速度)。

是可增量扩展的哈希表结构(当结构存储量增大的过程中, cache_t会增量扩大它的内存空间来支持更多的缓存,用哈希表实现这个数据结构,是为了提高查找效率)。

cache_t数据结构是计算机局部性原理的最佳应用(计算机局部性原理:在一般调用方法时,有几个方法调用频次较高,把他们放到方法缓存中,下次的命中率就会更高)。

cache_t具体数据结构说明:


可以理解为是数组来实现的

每个对象都是bucket_t这样的一个结构体, bucket_t有两个主要成员变量,key和IMP。key对应OC中的selector,在调用方法时是个选择器SEL。

IMP理解为无类型的函数指针,可以通过方法选择器的名称key来寻找这个方法的具体实现IMP。

假如现在有个key,可以通过哈希查找算法来定位当前key所对应的bucket_t位于数组当中哪个位置,然后从这个位置中提取出bucket_t中的IMP

class_data_bits_t

这个结构是objc_class中的成员结构

class_data_bits_t主要是对class_rw_t的封装。

class_rw_t代表了类相关的读写信息,例如给类添加的分类的一些方法,属性以及协议等,同时它也对class_ro_t的封装,我们可以随时创建分类,为类增加属性或者方法。rw是readWrite的简写,ro是readOnly的意思,创建类时,添加的成员变量或方法列表在之后就没办法修改了

class_ro_t代表了类相关的只读信息。


包含

1.class_ro_t

2.protocols类分类中的协议

3.properties类分类中的属性

4.methods类分类中的方法

这三个数据结构是个二维数组

假如我们三个分类A、B、C,编译顺序A->B->C。这时会逆序遍历并打包成分类数组,分类C中的所有方法都在第一列竖列表中,存在二维数组的第1项。分类B中的所有方法都在第二列竖列表中,存在二维数组的第2项。分类A中的所有方法都在第三列竖列表中,存在二维数组的第3项。


1.name:类名

2.ivars:声明的类的成员变量

3.类的属性

4.类的协议

5.类的方法列表

除1外都是一维数组

在方法列表当中存储的内容,一般是分类中添加的方法

method_t实际上是对方法的抽象说明

method_t

method_t是对函数四要素(名称、返回值、参数、函数体)的封装

函数四要素决定了函数的唯一性


method_t是个结构体,主要有三个数据类型

1.name函数名称

2.types 函数返回值和参数的集合

3.imp 无类型的函数指针,对应着函数体


苹果的Type Encodings技术

types成员属性,实际上表达结构是:

第一个位置永远是函数的返回值类型,后面跟着每个参数的参数类型

参数可以有多个,返回值只有一个

V@:代表types所存储的内容

V对应返回值,@对应参数1,:对应参数2

二、消息的转发机制

https://github.com/LeesimEverglow/LMMessageForwardDemo    demo地址

参考资料:https://www.jianshu.com/p/fdd8f5225f0c

消息转发机制共分为3大步骤:

1.Method resolution 方法解析处理阶段处理对象或者类本身是否能响应某方法

2.Fast forwarding 快速转发阶段,某对象的属性中也许该包含了其他类对象,但是这个类对象是否能响应该方法呢,则是快速转发

3.Normal forwarding 常规转发阶段 如果都不能响应,则会创建一个虚基类来看是都能接收,看虚基类能否响应该方法的签名,如果不能则最后抛出异常。

1.消息的转发和替换其实大面积有效的可以使用在混淆上面,让方法名进行混淆,代替执行。比如热更新的混淆

2.可以实现多重代理,让不同对象可以同时代理同个回调,然后在各自负责的区域进行相应的处理,降低了代码的耦合程度。

3.间接实现多继承Objective-C本身不支持多继承,这是因为消息机制名称查找发生在运行时而非编译时,很难解决多个基类可能导致的二义性问题,但是可以通过消息转发机制在内部创建多个功能的对象,把不能实现的功能给转发到其他对象上去,这样就做出来一种多继承的假象。转发和继承相似,可用于为OC编程添加一些多继承的效果,一个对象把消息转发出去,就好像他把另一个对象中放法接过来或者“继承”一样

三、消息的传递机制 (消息动态绑定机制)

参考:https://juejin.cn/post/6844904014669152270

四、runtime的实际应用

参考:https://www.jianshu.com/p/d761d5938c77



喜欢的朋友记得点赞、收藏、关注哦!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/936078.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端编辑器JSON HTML等,vue2-ace-editor,vue3-ace-editor

与框架无关 vue2-ace-editor有问题&#xff0c;ace拿不到&#xff08;brace&#xff09; 一些组件都是基于ace-builds或者brace包装的 不如直接用下面的&#xff0c;不如直接使用下面的 <template><div ref"editor" class"json-editor"><…

QT:在线安装与离线安装

QT 学习系列 QT&#xff1a;在线安装与离线安装 QT 学习系列一、安装&#xff08;一&#xff09;离线安装windows系统Linux 系统Mac 系统 &#xff08;二&#xff09;在线安装 二、 环境变量配置三、验证总结 一、安装 &#xff08;一&#xff09;离线安装 windows系统 获取…

国产固态继电器的演变:可靠的电源解决方案

家用国产固态继电器(SSR)已成为各行各业的基石&#xff0c;性能可靠、设计紧凑、效率高。这些先进的开关设备取代了传统的机电继电器&#xff0c;具有静音运行、使用寿命更长、可靠性更高等诸多优点。家用SSR专为从工业自动化到家用电器等各种应用而设计&#xff0c;展示了本地…

Java-DataX 插件机制示例

示例代码 DataXPluginExample: DataX 项目的plugin 机制学习https://gitee.com/wendgit/data-xplugin-example/ 摘要 DataXPluginExample 是一个我编写的专门解读DataX插件机制的示例项目&#xff0c;旨在深入解析和掌握DataX的插件机制。本示例通过简洁明了的实现方式&#…

Ubuntu boot-repair安装过程

本教程只是在UBuntu系统无法引导才使用的方法&#xff0c;有可能需要提前使用U盘刻录UBuntu镜像去引导。 假如winUBuntu双系统&#xff0c;找不到紫色的UBuntu界面了&#xff0c;请参考&#xff1a;windows10ubuntu双系统开机引导界面不见的解决办法_双系统不出现引导界面-CSD…

苹果公司即将为iPhone和智能家居改用自主研发的蓝牙和Wi-Fi芯片

美股快讯&#xff1a;苹果公司即将为iPhone和智能家居改用自主研发的蓝牙和Wi-Fi芯片 苹果公司计划从明年开始在其设备上改用国产芯片进行蓝牙和Wi-Fi连接&#xff0c;此举将逐步淘汰目前由博通提供的部分部件。这种代号为Proxima的芯片已经开发了数年&#xff0c;现在计划用于…

汽车车牌识别数据集,支持YOLO,COCO,VOC格式的标注,8493张图片,可识别多种环境下的车牌

汽车车牌识别数据集&#xff0c;支持YOLO&#xff0c;COCO&#xff0c;VOC格式的标注&#xff0c;8493张图片&#xff0c;可识别多种环境下的车牌 数据集分割 训练组82&#xff05; 6994图片 有效集12&#xff05; 999图片 测试集6% 500图片 预处理 自动…

Towards Frame Rate Agnostic Multi-object Tracking—迈向帧率无关的多目标跟踪

Towards Frame Rate Agnostic Multi-object Tracking—迈向帧率无关的多目标跟踪 发表在IJCV 2023年 作者&#xff1a;Weitao Feng, Lei Bai, Yongqiang Yao, Fengwei Yu & Wanli Ouyang 研究目标&#xff1a;多目标跟踪的帧率无关性研究 IJCV 在计算机视觉领域的影响力非常…

day11 性能测试(3)——Jmeter 断言+关联

【没有所谓的运气&#x1f36c;&#xff0c;只有绝对的努力✊】 目录 1、复习 2、查看结果树 多个http请求原因分析 3、作业 4、Jmeter断言 4.1 响应断言 4.1.1 案例 4.1.2 小结 4.2 json断言 4.2.1 案例 4.2.2 小结 4.3 断言持续时间 4.3.1 案例 4.3.2 小结 4.…

高项 - 信息化发展

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 博文更新参考时间点&#xff1a;2024-11-09 高项 - 章节与知识点汇总&#xff1a;点击跳转 文章目录 高项 - 信息化发展信息与信息化信息信息系统信息化 现代化基础设施新型基础设施建设工业互联网车联网 现代化创…

PostgreSQL中事件触发器Event Trigger

在PostgreSQL中&#xff0c;事件触发器&#xff08;Event Trigger&#xff09;是一种特殊的触发器类型&#xff0c;它允许你在特定的数据库系统事件发生时执行特定的操作。与普通的触发器不同&#xff0c;事件触发器并不与特定的表或视图相关联&#xff0c;而是与数据库级别的全…

移远EC200A-CN的OPENCPU使用GO开发嵌入式程序TBOX

演示地址&#xff1a; http://134.175.123.194:8811 admin admin 演示视频&#xff1a; https://www.bilibili.com/video/BV196q2YQEDP 主要功能 WatchDog 1. 守护进程 2. OTA远程升级 TBOX 1. 数据采集、数据可视化、数据上报&#xff08;内置Modbus TCP/RTU/ASCII,GPS协…

深度学习中的多通道卷积与偏置过程详解

目录 ​编辑 多通道卷积的深入理解 &#x1f50d; 卷积核的多维特性 &#x1f30c; 卷积操作的细节 &#x1f527; 多通道卷积的优势 &#x1f31f; 偏置过程的深入理解 &#x1f3af; 偏置的两种实现方式 &#x1f6e0;️ 偏置的作用与重要性 &#x1f308; 多通道卷…

在服务器自主选择GPU使用

比如说&#xff0c;程序使用第 2 张显卡&#xff08;从 0 开始计数&#xff09;。它的作用是告诉系统和深度学习框架&#xff08;如 PyTorch 或 TensorFlow&#xff09;只可见某些 GPU。 export CUDA_VISIBLE_DEVICES1 然后再查看当前使用的显卡&#xff1a; echo $CUDA_VIS…

Vue3+TypeScript+AntVX6实现Web组态(从技术层面与实现层面进行分析)内含实际案例教学

摘要 用Vue3+TypeScript+AntVX6实现Web组态(从技术层面与实现层面进行分析),包含画布创建、节点设计、拖拽实现(实际案例)、节点连线、交互功能,后续文章持续更新。 注:本文章可以根据目录进行导航 文档支持 AntVX6使用文档 https://x6.antv.antgroup.com/tutorial…

jmeter CLI Mode 传参实现动态设置用户数

一.需求 CLI 运行模式下每次运行想要传入不同的用户数&#xff0c;比如寻找瓶颈值的场景&#xff0c;需要运行多次设置不同的用户数。 二.解决思路 查看官方API Apache JMeter - Users Manual: Getting Started api CLI Mode 一节中提到可以使用如下参数做属性的替换&#…

SpringCloudAlibaba教程之注册中心Nacos

目录 概念 架构 设计原则 架构分层 用户层 业务层 内核层 插件 单机部署 1.下载安装包 2.安装nacos 3.启动nacos 快速开始 1.添加Maven依赖 2.添加配置 3.启动 集群部署 搭建步骤 1.搭建数据库&#xff0c;初始化数据库表结构 2.配置nacos 3.启动nacos集群…

Python大数据可视化:基于python的电影天堂数据可视化_django+hive

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 电影数据 看板展示 我的信息 摘要 电影天堂数据可视化是…

Unity屏幕截图、区域截图、读取图片、WebGL长截屏并下载到本地jpg

Unity屏幕截图、区域截图、读取图片、WebGL长截屏并下载到本地jpg 一、全屏截图并保存到StreamingAssets路径下 Texture2D screenShot;//保存截取的纹理public Image image; //显示截屏的Imagepublic void Jietu(){StartCoroutine(ScrrenCapture(new Rect(0, 0, Screen.width…

Go 语言与时间拳击理论下的结对编程:开启高效研发编程之旅

一、引言 结对编程作为一种软件开发方法&#xff0c;在提高代码质量、增强团队协作等方面具有显著优势。而时间拳击理论为结对编程带来了新的思考角度。本文将以 Go 语言为中心&#xff0c;深入探讨时间拳击理论下的结对编程。 在当今软件开发领域&#xff0c;高效的开发方法和…