当前位置: 首页 > news >正文

iOS -- isa指针

  1. isa指针:isa指针是一个指向对象所属类或元类的指针。它决定了对象可以调用的方法和属性。isa指针在对象的结构中存在,并且在运行时会被自动设置。
  2. isa 指针,表示这个对象是一个什么类。而 Class 类型, 也就是 struct objc_class * ,这是苹果在下面的注释中写到的。这说明类本身也是一个对象。在类对象中的 isa 指向的类叫做“元类”,类方法就定义在元类中。总的来说就是,一个类可以有很多的实例,这些实例有着唯一的一个类对象,而这个类对象也有着唯一的一个元类。
  3. 在这里插入图片描述

在Objective-C中,每个对象都有一个isa指针,它指向该对象所属的类或元类。isa指针决定了对象可以调用的方法和属性。通过isa指针,Objective-C运行时可以在运行时动态地确定对象所属的类,并在该类或其父类中查找对应的方法实现。
下面是一些示例代码来说明isa指针的作用:

@interface MyClass : NSObject
- (void)myMethod;
@end@implementation MyClass
- (void)myMethod {NSLog(@"MyClass's myMethod");
}
@endint main() {MyClass *myObject = [[MyClass alloc] init];[myObject myMethod];return 0;
}

在上面的示例中,创建了一个名为MyClass的类,它继承自NSObjectMyClass类中定义了一个名为myMethod的方法。

当我们创建一个MyClass对象并调用myMethod方法时,实际上发生了以下过程:

  1. 分配内存并初始化MyClass对象。
  2. 运行时为该对象设置isa指针,使其指向MyClass的类对象。
  3. myObject上调用myMethod方法时,运行时首先通过isa指针找到MyClass的类对象。
  4. 运行时在类对象中查找名为myMethod的方法实现并执行。

通过这个过程,我们可以看到isa指针在动态确定对象所属的类的过程中起到了关键作用。它使得我们可以在运行时根据对象的实际类型来调用适当的方法。

isa,类对象,元类对象

OC的对象及其alloc和init。验证了OC对象底层是结构体,然后在alloc的方法调用栈的最后一个关键方法creatinstance中,有一个创建isa指针的方法。这篇,我们就先聊一聊isa指针。
我们知道,OC中的绝大部分对象,都是继承自NSObject(目前我已知的只有一个 NSProxy 类不继承自NSObject,它跟NSObject一样,是基类)。按住command键,跳进NSObject的头文件,就能看到下面的代码:

@interface NSObject <NSObject> {#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-interface-ivars"Class isa  OBJC_ISA_AVAILABILITY;#pragma clang diagnostic pop
}

这就是NSObject的声明了,它只有一个isa指针,万物继承自NSObject,就有了自己的isa指针了。那这个isa到底有什么用呢?它究竟是个啥东西?

位域

在说isa之前,我们先了解一下[[共用体]]和[[位域]]这种技术。

在armv7、armv7s时代,由于是32位操作系统,苹果并没有对指针进行优化,实例对象的isa是直接指向类对象的。进入到arm64架构时代后isa占用8个字节,共计64位,如果只是单纯存一个指针太浪费,所以,苹果通过共用体技术,充分的让这64位存储了非常多的信息,不用再额外的开辟空间来存储,减少了内存开支,减少了内存的操作。下面我们具体看一下isa的结构。

isa的定义

union isa_t {isa_t() { }isa_t(uintptr_t value) : bits(value) { }Class cls;uintptr_t bits;
#if defined(ISA_BITFIELD)struct{ISA_BITFIELD;  // defined in isa.h  说明在isa.h中};
#endif
};

里面有个ISA_BITFIELD,再看这个是怎么定义的:

# if __arm64__
#   define ISA_MASK        0x0000000ffffffff8ULL
#   define ISA_MAGIC_MASK  0x000003f000000001ULL
#   define ISA_MAGIC_VALUE 0x000001a000000001ULL
#   define ISA_BITFIELD                                                      \uintptr_t nonpointer        : 1;          //表明这个属性占一位,且从低位开始\uintptr_t has_assoc         : 1;          // 同上                       \uintptr_t has_cxx_dtor      : 1;                                       \uintptr_t shiftcls          : 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/ \uintptr_t magic             : 6;                                       \uintptr_t weakly_referenced : 1;                                       \uintptr_t deallocating      : 1;                                       \uintptr_t has_sidetable_rc  : 1;                                       \uintptr_t extra_rc          : 19
#   define RC_ONE   (1ULL<<45)
#   define RC_HALF  (1ULL<<18)

isa union共用体中各个位的含义

  • nonpointer 指示位,表示是否对isa指针开启指针优化,值为0表示纯isa指针 1表示不止是类对象的地址,isa中还包含了类信息、对象的引用计数等

  • has_assoc: 关联对象标志位,0没有,1存在(KVO的实现原理)

  • has_cxx_dtor :该对象是否有C++或者Objc的析构器,如果有析构函数,则需要做析构逻辑,如果没有,则可以更快的释放对象

  • shiftcls: 实际存储类指针的值。开启指针优化的情况下,在arm64架构中有33位用来存储类指针,也是基于此,不同的架构中,对于类指针的读取需要不同的操作,在32位时期,由于,由于未进行isa优化,isa是直接指向类对象的,在64位之后,需要用isa指针与上掩码(ISA_MASK)才能取到指针,这个指针指向类对象。

  • magic :用于调试器判断当前对象是真的对象还是没有初始化的空间

  • weakly_refrenced: 对象是否被指向或者曾经指向一个ARC的弱变量,没有弱引用的对象,可以更快的释放

  • dellocating :标志对象是否正在释放对象。ing表示进行时

  • has_sidetable_rc:当对象引用计数大于0时,则需要借用该变量存储进位。weak的实现原理,就是使用sidetables。后续讲到内存管理的时候会对此进行详细的讲解。

  • extra_rc:当表示该对象的引用计数值,实际上是引用计数值减1.例如,如果对象的引用计数为10,那么extra_rc为9,如果引用计数大于10,则需要使用到上面的has_sidetable_rc。

用64位存储了这么多的信息,相当的高效!!我当初知道这个点的时候,叹为观止!苹果真的把这种细节这种设计做到了极致。苹果的工程师们真他娘的都是人才,各个身怀绝技(也可能我作为井底之蛙,没有了解过这个技术)。

好,介绍过isa之后,接下来就该是实例对象、类对象、和元类对象了。

在arm64架构之后,isa通过shiftcls来指向类对象的。类对象也是个对象,也有isa指针,它的isa中的shiftcls是指向元类对象的。元类对象也有isa,它的shiftcls都指向根类的元类对象。 网上有一张非常经典的图来展示了对象和元类对象的关系(这幅图将贯穿大部分关于底层原理的博客内容)来看一下:
在这里插入图片描述

这个图用语言来描述一下,就是

  • 实例对象的isa指向的类对象,类对象的isa指向元类对象。元类对象的isa均指向基类的元类对象(基类的元类对象的isa指向自己)。需要特别注意,arm64架构后,isa不直接指向,需要先用掩码取出shift_cls指针,这个是实际的指向关系的指针。
  • 类对象和元类对象中有superclass指针,普通类对象的superclass指针指向父类的类对象,基类类对象的superclass指向nil。基础对象的元类对象的superclass指针指向父类的元类对象,基类的superclass指针指向父类的类对象。

写完这些我都不认识这个类字了。谨记这幅图,就能非常好的理解实例对象、类对象、元类对象之间的关系了。这个图画的非常好,在后面的runtime的消息转发流程中还会用到这幅图以及这些对象之间的关系。

为什么需要类对象和元类对象

那为啥要有类对象和元类对象呢?类对象和元类对象中都放着什么东西呢?

先说为什么。我们都知道,我们创建的类,有很多的属性、协议和方法,方法又分为实例方法和类方法。而这些方法的实现都是统一的,再调用的过程中,只是参数的值不同,所以这些方法存一份儿就够了,没必要在每个对象中都存一份。所以就有了类对象和元类对象。可以想一下平时写的方法调用的代码,假定Person类有一个实例方法叫-(void)instanceFunction,有个类方法+(void)classFunction。我们在调用的时候是这么调用的:

- (void)callFunctions{[person instanceFunction];     //使用实例对象来调用实例方法[Person classFunction];        //使用类名(其实就是类对象)调用类方法
}

可以很明显的看出,方法调用者的不同。而这个不同就是由类对象、元类对象、isa来实现的。类对象中,存储了这个类的属性、协议和实例方法。元类对象中存储了这个类的类方法。在方法调用时,实例方法通过这个实例对象的isa找到这个类的对象,然后在类对象中查找这个方法。类方法通过类对象的isa找到这个类的元类对象,在元类对象中查找这个方法。通过这样的描述,结合上面的图,就能很好的理解isa指针、类对象和元类对象了。

好,简单的来总结一下今天的内容。主要是理清实例对象、类对象、元类对象之间的关系,要记住那副图,保证自己能完整的复述出他们之间的关系。isa就相当于纽带,将他们串联了起来。在最后提到了,类对象和元类对象是存储属性、协议和方法的,我们会在runtime中,具体的讲解这些信息是如何存储的。

相关文章:

iOS -- isa指针

isa指针&#xff1a;isa指针是一个指向对象所属类或元类的指针。它决定了对象可以调用的方法和属性。isa指针在对象的结构中存在&#xff0c;并且在运行时会被自动设置。isa 指针&#xff0c;表示这个对象是一个什么类。而 Class 类型&#xff0c; 也就是 struct objc_class * …...

【SA8295P 源码分析】14 - Passthrough配置文件 /mnt/vm/images/linux-la.config 内容分析

系列文章汇总见:《【SA8295P 源码分析】00 - 系列文章链接汇总》 本文链接:《【SA8295P 源码分析】14 - Passthrough配置文件 /mnt/vm/images/linux-la.config 内容分析》 透传配置文件位于:qnx.git\apps\qnx_ap\target\hypervisor\gvm\ivi\la\linux-la.config 它是在QNX Ho…...

新型糖基化氨基酸:Fmoc-Thr((Ac4Galβ1-3)Me,Ac4Neu5Acα2-6AcGalNAcα)-OH,化学CAS号174783-92-7

●英文名&#xff1a;Fmoc-Thr((Ac4Galβ1-3)Me,Ac4Neu5Acα2-6AcGalNAcα)-OH ●外观以及性质&#xff1a; Fmoc-Thr((Ac4Galβ1-3)Me,Ac4Neu5Acα2-6AcGalNAcα)-OH中通过对蛋白进行复杂蛋白糖基化修饰&#xff0c;细胞产生了极大丰度的蛋白质类型&#xff1b;通过对各类糖基…...

网络安全(黑客)怎么自学?

最近看到很多问题&#xff0c;都是小白想要转行网络安全行业咨询学习路线和学习资料的&#xff0c;作为一个培训机构&#xff0c;学习路线和免费学习资料肯定是很多的。机构里面的不是顶级的黑阔大佬就是正在学习的同学&#xff0c;也用不上这些内容&#xff0c;每天都在某云盘…...

Vue学习 之 MacOS 安装 webpack

Vue学习 之 MacOS 安装 webpack webpack 简介 Webpack 是一个非常流行的前端构建工具&#xff0c;它可以将多个模块&#xff08;包括CSS、JavaScript、图片等&#xff09;打包成一个或多个静态资源文件&#xff08;bundle&#xff09;&#xff0c;以便用于部署到生产环境。We…...

媒介易教你海外品牌推广:如何选择适合的新闻通稿发布平台?

在进行海外品牌推广时&#xff0c;选择合适的海外新闻通稿发布第三方平台是提高品牌曝光度和影响力的重要一环。这些平台可以帮助企业将新闻内容传播到全球范围内的媒体和受众&#xff0c;为品牌推广提供更广阔的机会。然而&#xff0c;选择合适的发布平台并不容易&#xff0c;…...

网络安全的学习路线是怎么样的?

最近看到网上有很多人在问诸如&#xff1a;“怎样成为网络安全工程师”等相关问题&#xff0c;这可能与近几年网络安全事件频发&#xff0c;国家对于互联网信息安全和互联网舆情的重视程度不断提升有关&#xff0c;网络信息安全工程师随之成为炙手可热的职业。关于职业前景的详…...

QT学习07:五种按钮控件

文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 文章目录 抽象类&#xff1a;QAbstractButtonQPushButtonQToolButtonQCommandLinkButtonQRadioButtonQCheckBoxQButtonGroup 抽象类&#xff1a;QAbstractButton 是所有按钮类的祖先。 QAbstractButton的信号&#xff1a…...

chatgpt赋能python:Python如何截图运行结果

Python如何截图运行结果 介绍 Python是一种高级编程语言&#xff0c;非常流行。它具有许多有用的功能和库&#xff0c;使其成为许多开发人员的首选编程语言之一。但是&#xff0c;当您运行Python程序并需要与他人共享结果时&#xff0c;您可能需要截图运行结果。在本文中&…...

Baumer工业相机堡盟工业相机如何通过BGAPISDK使用JPEG图像压缩功能(C#)

Baumer工业相机堡盟工业相机如何通过BGAPISDK使用JPEG图像压缩功能&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机BGAPISDK和JPEG图像压缩功能的技术背景Baumer工业相机通过BGAPISDK使用JPEG图像压缩功能1.引用合适的类文件2.使用BGAPISDK设置堡盟相机JPEG图像压缩模…...

RT-Thread FAL组件

目录 1、FAL介绍2、使用FAL2.1 下载FAL软件包2.2 FAL移植2.2.1 定义flash设备2.2.2 定义flash设备表&分区表2.2.3 加入到mdk工程3、MSH测试1、FAL介绍 FAL(Flash Abstraction Layer) Flash抽象层,是对Flash及基于Flash的分区进行管理、操作的抽象层,对上层统一了Flash及分…...

【git切换分支/tag】git stash保存暂不提交的更改

目录 问题git stash使用方法git stash pop 还原修改 git stash使用、修改指定tag的代码 其他git指令 问题 情景&#xff1a;分支1上开发新功能&#xff0c;临时切换到其他分支或tag上修改bug。 1、直接切换&#xff1a;如果没有冲突&#xff0c;分支1的修改会带到要切换的分支…...

【爬虫】4.5 实践项目——爬取当当网站图书数据

目录 1. 网站图书数据分析 2. 网站图书数据提取 3. 网站图书数据爬取 &#xff08;1&#xff09;创建 MySQL 数据库 &#xff08;2&#xff09;创建 scrapy 项目 &#xff08;3&#xff09;编写 items.py 中的数据项目类 &#xff08;4&#xff09;编写 pipelines_1.py …...

Socket 编程:基础概念辨析

文章目录 参考Socket APIBSD UNIX 操作系统BSD UNIX 与 Socket API Socket套接字套接字地址套接字 VS 套接字地址套接字的表示方法 TCP 套接字与 UDP 套接字TCP 套接字监听套接字连接套接字 UDP套接字 TCP 服务器端与 TCP 客户端通信的基本流程服务器端客户端 参考 项目描述刘…...

git lfs下载指定文件git lfs pull --include=“*.bin“

git lfs pull --include"*.bin"...

JavaScript 数组 函数

目录 1.数组的概念 2.创建数组 2.1 数组创建的方式 2.2利用new 创建数组 2.3 利用数组字面量创建数组 2.4 数据元素的类型 3.获取数组当元素 3.1数组元素的索引 4.遍历数组 4.1数组的长度 5.数组中新增元素 5.1通过修改length 长度新增数组元素 5.2通过修改数组索引…...

【哈佛积极心理学笔记】第7讲 逆境还是机遇

第7讲 逆境还是机遇 How can we raise base level? One of the things is coping, putting ourselves on the line. How to become an optimist. Optimism as an interpretation style, not as a Pollyannaish feel good kind of approach. Three approaches: First is to t…...

java springboot整合MyBatis做数据库查询操作

首先 我们还是要搞清楚 MyBatis 工作中都需要那些东西 首先是基础配置 你要连哪里的数据 连什么类型的数据库 以什么权限去连 然后 以 注解还是xml方式去映射sql 好 我们直接上代码 我们先创建一个文件夹 然后打开idea 新建一个项目 然后 按我下图的操作配置一下 然后点下一…...

11 二阶矩方法和Lovasz局部引理

文章目录 11 二阶矩方法和Lovasz局部引理11.1 The Second-Moment Method——二阶矩方法11.1.1 二阶矩方法定理11.1.2 二阶矩方法的应用——随机图阈值 11.2 Lovasz Local Lemma——Lovasz局部引理11.2.1 LLL定理11.2.2 LLL定理证明 11.3 Asymmetric LLL 11 二阶矩方法和Lovasz局…...

低代码赛道拥挤 生态聚合成为破局关键

在云计算和移动互联网的强劲推动下&#xff0c;企业数字化转型的步伐正在加速&#xff0c;对于软件应用开发的需求也呈现出爆发式的增长。这样的背景下&#xff0c;低代码平台凭借其独特的优势迅速崛起并引发了业界的广泛关注。 自2020年以来&#xff0c;低代码领域已成为投资…...

B+树:高效存储与索引的完美结合

目录 引言&#xff1a;一、定义&#xff1a;二、B树和B树三、特点&#xff1a;四、应用场景&#xff1a;总结&#xff1a; 引言&#xff1a; 在计算机科学领域中&#xff0c;数据结构的选择对于高效存储和索引数据至关重要。B树&#xff08;B tree&#xff09;作为一种自平衡的…...

左右排版的PDF,如何转换为单栏排版的word?

将左右排版的PDF转换为单行排版的WORD文字版需要进行以下步骤&#xff1a; 1. 使用PDF转换工具将PDF转换为WORD格式。有很多在线或离线的PDF转WORD工具可供选择&#xff0c;例如金鸣表格文字识别、Adobe Acrobat、Smallpdf、Zamzar等。 2. 打开WORD文档后&#xff0c;选择“页…...

D349周赛:注意题目提示里,数据范围隐含的算法复杂度提示

文章目录 6470.既不是最大值也不是最小值完整版为什么两个for循环时间复杂度还是不变的 6465.执行子串操作后的字典序最小字符串思路最开始的写法题意理解的问题 修改版a必须单独拿出来的原因 6449.收集巧克力思路注意提示信息 完整版补充&#xff1a;由数据范围反推算法复杂度…...

iOS -- block one

demo贴上我的github blockOne 块类似于匿名函数或闭包&#xff0c;在许多其他编程语言中也存在类似的概念。 Block 以下是块的一些基本知识&#xff1a; 块的定义&#xff1a;块是由一对花括号 {} 包围的代码片段&#xff0c;可以包含一段可执行的代码。块的定义使用 ^ 符号…...

第十二篇:强化学习SARSA算法

你好&#xff0c;我是郭震&#xff08;zhenguo) 今天强化学习第二十篇&#xff1a;强化学习SARSA算法 1 历史 SARSA&#xff08;「State-Action-Reward-State-Action」&#xff09;算法是一种经典的强化学习算法&#xff0c;用于解决马尔可夫决策过程&#xff08;MDP&#xff0…...

电力vr智能巡检模拟实操教学灵活性高成本低

传统电力智能运检服务培训采用交接班期间开展智能带电检测仪器的操作培训&#xff0c;教学时间、场地及材料有限&#xff0c;有了VR技术&#xff0c;将推动电力智能运检服务培训走向高科技、高效率和智能化水平。 深圳华锐视点凭借着对VR实训系统的深入研发和升级&#xff0c;多…...

vscode右键点击,松开后自动触发鼠标所在位置的按钮(误触发双击效果)

例如如下&#xff0c;右键展开菜单&#xff0c;松手会自动触发转到声明功能 解决方案&#xff1a; 1、安装easystroke sudo apt-get install easystroke 2、打开easystroke&#xff0c;选择preferences tab 3、点击Gesture Button&#xff0c;在出现的框中右键单击一次 4、点…...

【UE5】分分钟简单使用像素流云服务(Pixel Streaming)

【UE5】分分钟简单使用像素流云服务&#xff08;Pixel Streaming&#xff09; 前言 UE5的Pixel Streaming已经封装的很好&#xff0c;简单三步实现简单的服务搭建。 安装插件打包项目运行服务 注&#xff1a;实例平台为Windows 安装插件 编辑→插件→输入查询Pixel Strea…...

2021 年全国硕士研究生入学统一考试管理类专业学位联考逻辑试题

2021 年全国硕士研究生入学统一考试管理类专业学位联考逻辑试题 一. 逻辑推理&#xff1a;第 26~55 小题&#xff0c;每小题 2 分&#xff0c;共 60 分。下列每题给出的 A、B、C、D、E 五个选项中&#xff0c;只有一项是符合试题要求的。 26.哲学是关于世界观、方法论的学问。哲…...

【算法】【算法杂谈】两个排序数组中找第k小的数

目录 前言问题介绍解决方案代码编写java语言版本c语言版本c语言版本 思考感悟写在最后 前言 当前所有算法都使用测试用例运行过&#xff0c;但是不保证100%的测试用例&#xff0c;如果存在问题务必联系批评指正~ 在此感谢左大神让我对算法有了新的感悟认识&#xff01; 问题介…...

网站建设制作一个网站的费用/如何写软文推广产品

字符串与字节数组的转换 String str "helloworld"; byte data[] str.getBytes(); for(int x 0 ; x < data.length ; x) { data[x]- 32 ; System.out.print(datd[x] ,); } System.out.println(new String(data)); 通过程序可以发现&#xff0c;字节并不适合处…...

免费下载建设银行官方网站/武汉网站seo服务

最近一直再跟同一个项目UEEEU&#xff0c;干了很多事&#xff0c;锻炼自然也很多&#xff0c;这阵子也是从早到晚的忙活&#xff0c;身体似乎都不知疲惫的说&#xff0c;其实忙着也好&#xff0c;有钱有经验嘛&#xff0c;多踏实哈。这一年来又变了很多&#xff0c;进步很多&am…...

辽宁省大学生创新创业平台/杭州优化公司哪家好

本节书摘来自华章计算机《需求设计&#xff1a;构建用户想要和需要的产品》一书中的第2章&#xff0c;第2.2节,作者&#xff1a; [英] 克里斯布里顿&#xff08;Chris Britton&#xff09; 更多章节内容可以访问云栖社区“华章计算机”公众号查看。 2.2 情境设计 情境设计需要…...

徐州市水利工程建设有限公司网站/网络营销公司好不好

1.什么是分布式锁 线程锁主要用来给方法&#xff0c;代码加锁。当某个方法或代码使用锁&#xff0c;在同一时刻仅有一个线程执行改方法或改代码段。线程锁只在同一JVM中有效果&#xff0c;因为线程锁的实现在根本上是依靠线程之间共享内存实现的&#xff0c;进程锁是为了控制…...

wordpress分享获得积分/网址导航该如何推广

主要考察组合数知识&#xff0c;初始化的时候参考公式首先先推个公式&#xff0c;就是长度为len的Round Numbers的个数。长度为len,第一位肯定是1了。那么后面剩下 len-1位。如果len-1是偶数。那么 C&#xff08;len-1,(len-1)/21)C&#xff08;len-1,(len-1)/22)C(len-1,len-…...

网站开发产生的材料/地推app接任务平台

财务报表是反映企业或预算单位一定时期资金、利润状况的会计报表。财务报表包括资产负债表、损益表、现金流量表或财务状况变动表、附表和附注。财务报表工具提高了会计在进行财务统计的效率。 财务报表是财务报告的主要组成部分&#xff0c;它所提供的会计信息具有重要作用&am…...