【iOS】class的底层结构总结

news2024/12/29 11:27:04

class的结构

方法缓存

我们先来整体看一下结构
在这里插入图片描述

    1. class类中只有isa指针、superClass、cache方法缓存、bits具体的类信息
    1. bits & FAST_DATA_MASK 指向一个新的结构体Class_rw_t, 里面包含着methods方法列表、properties属性列表、protocols协议列表、class_ro_t类的初始化信息 等一些类信息

class_rw_t

class_rw_t里面的methods方法列表、properties属性列表 都是二维数组,是可读可写的,包含 类的初始内容,分类的内容
在这里插入图片描述

class_ro_t

class_ro_t 里面的baseMethodList, baseProtocols, Ivars, baseProperties是一维数组, 是只读的, 包含类的初始化内容

在这里插入图片描述

method_t

method_t是对方法的封装

struct method_t{
  SEL name;    //函数名
	const char *types;  //编码(返回值类型,参数类型)
	IMP imp;    //指向函数的指针(函数地址)
}

IMP

IMP代表函数的具体实现

typedef id _Nullable (*IMP)(id _Nonnull, SEL _Nonnull, …);

  • id _Nonnull : 第一个参数是指向self的指针. (如果是实例方法,则是类实例的内存地址;如果是类方法,则是指向元类的指针)
  • SEL _Nonnull : 第二个参数是方法选择器(selector)
  • 每一个OC方法,都有两个隐藏参数
  1. self参数,指向当前实例的指针,用于访问对象的属性和方法。
    • 在实例方法中,self指向当前对象实例
    • 在类方法中,self指向当前类对象
  2. _cmd参数
    • _cmd是一个SEL类型的参数,表示当前正在执行的方法选择器(方法名)
    • 它可用于在运行时获取的当前方法的名称,比如在日志中输出当前方法的名称。

SEL

SEL代表方法名,一般叫选择器,底层结构跟char *类似

  • 可以通过@selector() 和 sel_registerName()获得
  • 可以通过sel_getName() 和 NSStringFromSelector()专程字符串
  • 不同类中相同名字的方法, 所对应的方法的选择器是相同的
  • 具体实现 typedef struct objc_selector *SEL

types

types包含了函数返回值,参数编码的字符串
结构为:返回值 参数1 参数2 … 参数N
iOS中提供了一个叫做@encode的指令,可以将具体的类型表示成字符串编码

在这里插入图片描述

例如

// “i24@0:8i16f20”
// 0id 8SEL 16int 20float == 24

  • (int)test:(int)age height:(float)height

每一个方法都有两个默认参数self和_msg,我们可以查到id类型为@, SEL类型为:
- 1. 第一个参数i返回值
- 2. 第二个参数@是id类型的self
- 3. 第三个参数:是SEL类型的_msg
- 4. 第四个参数i 是Int age
- 5. 第五个参数f是float height
其中加载的数字其实是跟所占字节有关的
- 1. 24总共占有多少字节
- 2. @0 是 id类型的self 的起始位置为0
- 3. :8是因为 id类型的self占8字节,所以SEL类型的_msg的起始位置为8

方法缓存

Class内部结构中有一个方法缓存cache_t, 用散列表(哈希表)来缓存曾经调用过的方法, 可以提高方法的查找速度。

在这里插入图片描述

cache_t结构体里面有三个元素
- buckets 散列表, 是一个数组,数组里面的每一个元素就是一个结构体bucket_t , bucket_t 里面存放两个
- _key : SEL方法名作为key
- _imp : 函数的内存地址
- _mask : 散列表的长度
- _occupied : 已经缓存的方法数量

为什么会用到方法缓存

在这里插入图片描述

这张图片是我们方法产找路径,如果我们的一个类有多个父类,需要调用父类方法,他的查找路径为

    1. 先遍历自己所有的方法
    1. 如果在自己类中找不到方法,则遍历父类所有方法,没有查找到调用方法之前, 一直重复该动作。如果每一次方法调用都是走这样的步骤, 对于系统级方法来说,其实还是比较消耗资源的,为了应对这个情况。出现了方法缓存,调用过的方法,都放在缓存列表中,下次查找方法的时候,先在缓存中查找,如果缓存中查找不到,然后在执行上面的方法查找流程。

散列表结构

在这里插入图片描述

散列表的结构大概就像上面那样,数组的下标是通过@selector(方法名)&_mask来求得,具体每一个数组的元素是一个结构体, 里面包含两个元素_imp和@selector(方法名)作为的key

我们在上一篇文章中知道,一个值与&上一个_mask,得出的结果一定小于等于_mask值,而_mask值为数组长度-1,所以任何时候,也不会越界。

其实这就是散列表的算法,也有一些其他的算法,取余,一个值取余和&的效果是相同的。

但是这其实是有几个疑虑的

- 1. 初始 _mask是多少? - 初始_mask为简单尝试了一下,`第一次可能为3`
- 2. 随着方法的增加,方法数量超过_mask值了怎么办?  -    随着方法的增多,方法数量肯定会超过_mask, 这个时候会`清空缓存散列表,然后_mask*2`
- 3.  如果两个值&_mask的值相同了怎么办?  -   如果两个值&_mask的值相同时,第二个&减一,直到找到空值,如果减到0还没有找到空位置,那就放在最大位置
- 4. 在没有存放cach_t的数组位置怎么处理?
    - 在没有占用时,会在空位置的值为NULL

面试题

  1. class_rw_t和class_ro_t结构体中,都有方法列表,属性列表,协议列表,有什么区别呢?

答:

  1. 方法列表:
    - class_ro_t中存储了类的所有静态方法包括从父类继承的方法。这些方法在类的编译时就被确定下来了。
    - class_rw_t中存储了类的动态方法列表,包括在运行时添加或修改的方法。

  2. 属性列表:
    - class_ro_t中存储了类的所有静态属性包括从父类继承的方法。这些属性在类的编译时就被确定下来了。
    - class_rw_t中存储了类的动态属性列表,包括在运行时添加或修改的属性。

  3. 协议列表:
    - class_ro_t中存储了类遵循的所有静态协议,这些协议在类的编译时就被确定下来了。
    - class_rw_t中存储了类在运行时动态遵循的协议列表

  4. 讲一下class的结构,class_rw_t的结构,class_ro_t的结构

在这里插入图片描述

  1. 讲一下这三者的关系

class结构中有一个bits,通过&FAST_DATA_MASK得到class_rw_t结构,class_rw_t结构体中一个成员变量const class_ro_t *ro;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C# 设计模式之外观模式

总目录 前言 在软件开发过程中,要完成一个功能,可能需要调用很多接口,不仅增加了代码间的耦合度,也增加了调试成本和维护的复杂度。不如我们把这些接口再封装一次,给一个很好的“外观”,让使用者使用更方便…

14. 计算机网络HTTPS协议(二)

1. 前言 上一章节中我们主要就 HTTPS 协议的前置知识进行介绍,下面会继续介绍 HTTPS 的通信过程以及抛出一些常见问题的探讨。因为候选人准备面试的时间和精力是比较有限的,我们在学习的过程要抓住重点,如果感觉对于细节缺乏了解,可以通过维基百科和查阅 StackOverflow 等…

美国大语言模型军事应用典型案例

源自:北京科技大学机械工程学院 作者:陈哲涵 黎学臻 注:若出现无法显示完全的情况,可 V 搜索“人工智能技术与咨询”查看完整文章 人工智能、大数据、多模态大模型、计算机视觉、自然语言处理、数字孪生、深度强化学习 课程也可…

AbMole革命性发现:CUDC-907——单一分子双重抑制PI3K与HDAC的创新突破

在生物医学研究的浩瀚宇宙中,科学家们不断探索着新的方法来对抗复杂的疾病机制。今天,我们要探讨的是一项令人瞩目的研究成果——CUDC-907,这一创新分子在抑制PI3K(磷脂酰肌醇3-激酶)和HDAC(组蛋白去乙酰化…

c++——map、set底层之AVL树(动图演示旋转)

在上一篇博客里面我们提到了set和map的使用;这篇博客重点介绍他们的底层逻辑 c之set和map——关联容器(非顺序容器——list、vector) 目录 文章目录 前言 一、底层结构 二、AVL 树 1.AVL树的概念 2.AVL树节点的定义 3、AVL树的插入 三、 AVL树…

Databend 开源周报第 156 期

Databend 是一款现代云数仓。专为弹性和高效设计,为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务:https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展,遇到更贴近你心意的 Databend。 支持 Share Cata…

深入解读 Scrapy 框架原理与源码

🛠️ Scrapy 框架原理解读 Scrapy 是一个强大的 Python 爬虫框架,其设计理念基于事件驱动的异步编程,通过高度模块化的方式实现爬虫功能。Scrapy 框架的核心组成包括爬虫(Spider)、调度器(Scheduler&#…

大模型书籍推荐:《大规模语言模型:从理论到实践》

书籍简介 在当前的人工智能领域,大规模语言模型(Large Language Models, LLMs)无疑是最重要的研究方向之一。它们不仅在自然语言处理方面取得了显著成果,还为其他领域带来了革命性的变化。《大规模语言模型:从理论到实…

维语驾考这款软件有人用过吗?靠谱吗?

维语驾考是专门为维吾尔语学车考驾照的学员而准备的驾考刷题软件。书写延续维语用法自右向左书写,可调节字号大小,支持维汉双语切换。2024驾考新规题库,内含科目一、科目四全真题库,每道题配备详细解析,帮助学员理解透…

Openwrt配置ZeroTier,实现公网访问内网中服务器

ZeroTier注册&Openwrt初始配置 首先来到Openwrt的VPN→ZeroTier页面,进行一个很简单的注册 注册后去zerotier的网页管理页面进行一个很简单的创建网络 复制网络ID备用 在openwrt填写网络ID并启用。如果你需要访问内网主机勾上 自动客户端NAT 在zerotier网络管理…

电子合同签署:2024年十佳选择与评估

文章将介绍10款电子合同签署平台:e签宝、上上签、合同宝、腾讯电子签、合易签、Zoho Sign、Nitro Sign、Secured Signing、Signeasy、Lightico。 在当今快速发展的商业环境中,选择一款合适的电子合同签署平台对于保证工作效率和合同执行的安全性至关重要…

精准洞察农田生态,智慧农业物联网环境监测与数据采集系统来袭

随着智慧农业的快速发展,利用物联网技术实现对农田种植状态的精准监测变得愈发重要。为了确保监测的准确性、一致性和有效性,规范农田物联网监测设备的技术参数、部署安装以及数据对接等技术指标势在必行。 本文技术说明旨在为相关设备的选择、安装和集…

深入源码P3C-PMD:rule (4)

系列文章目录 文章目录 系列文章目录rule 的应用类别 rule rule 自定义XML rule 定义Tree 漫游错误报告生命周期 designer rule相关的代码在每个子 module 的 rule 文件夹。而且也以一些 ruleset 为范围分了文件夹,如下图所示: 对每个 rule 来说&#xf…

Model Counting 2024 Public Instance Track 1 18000s(5h)测试结果

测试求解器:SharpSAT-TD与SharpSATTD-CH 18000s测试结果 测试结果图 对3600s未得到结果的数据进行18000s的测试,48组数据,最终有4组在18000s(5h)内解出 测试数据117 SharpSAT-TD输出: SharpSATTD-CH输出…

2024年底前,河南建筑装饰企业资质延期资料准备要点

针对2024年底前河南建筑装饰企业资质延期的资料准备要点,结合当前的政策要求和实际情况,以下是一些关键的准备要点: 一、了解政策与要求 政策关注: 密切关注河南省住房和城乡建设厅及地方建设主管部门发布的最新政策文件、通知公…

万字长文带你入门shell编程(超详细)

一、概述 Shell 是计算机操作系统中用户与操作系统内核之间的接口层,它提供了一种方式让用户能够通过命令行界面(CLI)与操作系统交互。Shell 可以被视为一个命令解释器,它接收用户输入的命令,解析这些命令&#xff0c…

趋动科技助力中国移动新型智算中心AI算力池化商用实践

由中国通信标准化协会、中国通信学会指导,CCSA TC610 SDN /NFV /AI标准与产业推进委员会主办的2024年云网智联大会于4月10日-11日在北京召开。 趋动科技联合申报的“中国移动新型智算中心AI算力池化商用实践”,获得2023年度SDN、NFV、网络AI优秀案例征集…

欧美农场小游戏 高端链游 休闲的欧美链游农场 【玫瑰庄园】 高端中英-欧美花园链游

#农场小游戏#链游【玫瑰庄园】 高端中英-欧美花园链游 玫瑰花园一、种子:种子分为五种:白玫瑰、红玫瑰、黑玫瑰、紫罗兰、郁金香。种子通过开启盲盒获得。二、种花:玩家开启盲盒获得的种子,会直接种下,种子种下后&…

深入浅出消息队列----【如何保证消息不重复?】

深入浅出消息队列----【如何保证消息不重复?】 消息一定会重复消息幂等消费改造业务符合天然幂等写法数据库唯一索引redis 唯一判断 本文仅是文章笔记,整理了原文章中重要的知识点、记录了个人的看法 文章来源:编程导航-鱼皮【yes哥深入浅出消…