[iOS]浅析isa指针

[iOS]浅析isa指针

文章目录

  • [iOS]浅析isa指针
    • isa指针
      • isa的结构
      • isa的初始化
      • 注意事项

上一篇留的悬念不止分类的实现
还有isa指针到底是什么 它是怎么工作的
class方法又是怎么运作的
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
这里面的class又是何方神圣
话不多说 let‘s go!

isa指针

每个OC对象都含有一个isa指针,arm64之前,isa仅仅是一个指针,保存着对象或类对象内存地址,在arm64架构之后,Apple对isa进行了优化,变成了一个共用体(union)结构,同时使用位域来存储更多的信息

isa的结构

直接上源码看看
在这里插入图片描述
很显然isa是一个共用体而且其中两个互斥成员变量为
私有的 Class cls
公共的 uintptr_t bits

bits在不同架构和不同运行平台上有不同的定义
我们这里看看arm64e架构的真机下bits的定义
在这里插入图片描述

  1. nonpointer:表示是否对 isa 指针开启指针优化 0:纯isa指针,1:不止是类对象地址,isa中包含了类信息、对象的引用计数等
  2. has_assoc:关联对象标志位,0没有,1存在 has_cxx_dtor:该对象是否有 C++ 或者Objc 的析构器,如果有析构函数,则需要做析构逻辑, 如果没有,则可以更快的释放对象。
  3. shiftcls:存储类指针的值。开启指针优化的情况下,在 arm64 架构中有 33 位用来存储类指针
  4. magic:用于调试器判断当前对象是真的对象还是没有初始化的空间
  5. weakly_referenced:对象是否被指向或者曾经指向一个 ARC的弱变量,没有弱引用的对象可以更快释放
  6. deallocating:标志对象是否正在释放内存
  7. has_sidetable_rc:当对象引用技术大于 10 时,则需要借用该变量存储进位
  8. extra_rc:当表示该对象的引用计数值,实际上是引用计数值减 1, 例如,如果对象的引用计数为 10,那么 extra_rc 为9。如果引用计数大于 10, 则需要使用到下面的 has_sidetable_rc

一张图解释它

在这里插入图片描述

isa的初始化

一切美好都有一个开始

    // 在alloc中将类和指针做绑定obj->initInstanceIsa(cls, hasCxxDtor);

然后是留下一个不错的初印象

inline void 
objc_object::initInstanceIsa(Class cls, bool hasCxxDtor)
{ASSERT(!cls->instancesRequireRawIsa());ASSERT(hasCxxDtor == cls->hasCxxDtor());//下方函数调用就是isa的初始过程initIsa(cls, true, hasCxxDtor);
}

还得有一次难忘的深入了解

inline void 
objc_object::initIsa(Class cls)
{initIsa(cls, false, false);
}inline void 
objc_object::initIsa(Class cls, bool nonpointer, UNUSED_WITHOUT_INDEXED_ISA_AND_DTOR_BIT bool hasCxxDtor)
{ ASSERT(!isTaggedPointer()); isa_t newisa(0);if (!nonpointer) {newisa.setClass(cls, this);} else {ASSERT(!DisableNonpointerIsa);ASSERT(!cls->instancesRequireRawIsa());#if SUPPORT_INDEXED_ISAASSERT(cls->classArrayIndex() > 0);newisa.bits = ISA_INDEX_MAGIC_VALUE;// isa.magic is part of ISA_MAGIC_VALUE// isa.nonpointer is part of ISA_MAGIC_VALUEnewisa.has_cxx_dtor = hasCxxDtor;newisa.indexcls = (uintptr_t)cls->classArrayIndex();
#elsenewisa.bits = ISA_MAGIC_VALUE;// isa.magic is part of ISA_MAGIC_VALUE// isa.nonpointer is part of ISA_MAGIC_VALUE
#   if ISA_HAS_CXX_DTOR_BITnewisa.has_cxx_dtor = hasCxxDtor;
#   endifnewisa.setClass(cls, this);
#endifnewisa.extra_rc = 1;}// This write must be performed in a single store in some cases// (for example when realizing a class because other threads// may simultaneously try to use the class).// fixme use atomics here to guarantee single-store and to// guarantee memory order w.r.t. the class index table// ...but not too atomic because we don't want to hurt instantiationisa = newisa;
}

你了解到爱情本质

创建了一个 isa_t 类型的 newisa 实例, 对其做赋值操作
news.bits初始化时候只设置了nonpointer,magic两个部分,其余部分都没有进行设置,故值都为0

看到藏在最后的那一句
isa = newisa

回到初次见面的地方

isa_t 是一个联合体, 有两个成员变量一个是 bits, 还有一个 是 cls。我们知道 联合体 中各变量是互斥的, 它的优点是内存使用更为精细灵活。 所以,也就是说, isa_t 有两种初始化方式:

  • bits 被赋值, cls 没有值或者值被覆盖;
  • cls 被赋值, bits 没有值或者值被覆盖。

记起未曾发现过的点点滴滴

常见的assert()函数作用是如果它的条件返回错误,则终止程序执行
assert的作用是计算表达式 expression 如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行

注意事项

这是针对优化后的isa
也就是共用体中启用bits的那些non-pointer isa

贴一篇博客
Non-pointer isa

不想翻译了
好饿 想回去吃夜宵然后睡觉了
朱军 我相信你们的英语能力;)

What does this mean for my code?

Don’t read obj->isa directly.

The compiler will complain if you do. Trust the Compiler. The Compiler is your friend. Use [obj class] or object_getClass(obj) instead

Don’t write obj->isa directly

Use object_setClass() instead

If you override +allocWithZone

you may initialize your object’s isa field to a “raw” isa pointer. If you do, no extra data will be stored in that isa field and you may suffer the slow path through code like retain/release. To enable these optimizations, instead set the isa field to zero (if it is not already) and then call object_setClass().

If you override retain/release to implement a custom inline retain count

consider removing that code in favor of the runtime’s implementation

The 64-bit iOS simulator currently does not use non-pointer isa. Test your code on a real arm64 device.

核心观点就是 别再直接读写修改咱的isa指针啦
多多通过使用给的方法来判断类吧
或者照搬源码里面对isa的操作也是极好的
另外奥
目前64位的模拟器没有用到这个non-pointer isa技术
请在真机上测试叭

What does this mean for debugging?

The debugger knows how to decode the class from the isa field. You should not need to examine it directly in most cases.

You can run your code with environment variable OBJC_DISABLE_NONPOINTER_ISA=YES to disable non-pointer isa for all classes. If your code works with this set and fails without it, you may be incorrectly accessing an isa field directly somewhere.

If you are writing a debugger-like tool, the Objective-C runtime exports some variables to help decode isa fields. objc_debug_isa_class_mask describes which bits are the class pointer: (isa & class_mask) == class pointer. objc_debug_isa_magic_mask and objc_debug_isa_magic_value describe some bits that help distinguish valid isa fields from other invalid values: (isa & magic_mask) == magic_value for isa fields that are not raw class pointers. These variables may change in the future so do not use them in application code.`

debugger对non-pointer isa啥都懂
遇到问题多反思反思你自己哪里有问题
为什么总是你有问题 我都遇不到
然后你自己想写debugger的话 小心上面的变量
它们迟早被改动

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

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

相关文章

python的tkinter、socket库开发tcp的客户端和服务端

一、tcp通讯流程和开发步骤 1、tcp客户端和服务端通讯流程图 套接字是通讯的利器,连接时要经过三次握手建立连接,断开连接要经过四次挥手断开连接。 2、客户端开发流程 1)创建客户端套接字 2)和服务端器端套接字建立连接 3&#x…

Linux·基本指令(下)

1. mv 指令 (move) 语法:mv[选项] 源文件或目录 目标文件或目录 功能:将源文件或目录剪贴到一个新位置,或给源文件或目录改名但不会改变其内容 常用选项: -f :force 强制,如果目标文件已经存在,…

HCIE-AI大模型直通车火热报名中

第一阶段:HCIA-AI Solution Architect(直播,39课时) 该阶段详细介绍 AI 大模型所需基础技术栈,包含深度学习基础、计算机视觉技术、自然语言处理技术、华为开源深度学习框架 MindSpore、注意力制、Transformer 架构&am…

Spock单元测试框架使用介绍和实践

背景 单元测试是保证我们写的代码是我们想要的结果的最有效的办法。根据下面的数据图统计,单元测试从长期来看也有很大的收益。 单元测试收益: 它是最容易保证代码覆盖率达到100%的测试。可以⼤幅降低上线时的紧张指数。单元测试能更快地发现问题。单元测试的性…

【spring boot】初学者项目快速练手

一小时带你从0到1实现一个SpringBoot项目开发_哔哩哔哩_bilibili 一、简介 二、项目结构 三、代码结构 1.生成框架 Spring Initializr 快速生成一个初始的项目代码,会生成一个demo文件 打开intellj idea,导入demo文件 2.目录结构 源码都放在src-ma…

“论软件维护方法及其应用”精选范文,软考高级论文,系统架构设计师论文

论文真题 软件维护是指在软件交付使用后,直至软件被淘汰的整个时间范围内,为了改正错误或满足 新的需求而修改软件的活动。在软件系统运行过程中,软件需要维护的原因是多种多样的, 根据维护的原因不同,可以将软件维护…

Lua基础知识入门

1 基础知识 标识符:标识符的定义和 C语言相同:字母和下划线_ 开头, 下划线_ 大写字母一般是lua保留字, 如_VERSION 全局变量:默认情况下,变量总是认为是全局的,不需要申明,给一个变…

电脑压缩视频文件 电脑压缩视频大小的方法

在数字化时代,视频已成为我们记录生活、分享快乐的重要工具。然而,大尺寸的视频文件常常让分享和存储变得棘手。如何在保持视频画质的前提下,轻松减小视频文件大小?今天,就让我们一起探索苹果电脑上的几种高效视频压缩…

HP Superdome2小型机监控指标解读

监控易是一款专注于IT基础设施监控的软件,能够实时监控服务器的各项性能指标,确保服务器的稳定运行。针对HP Superdome2小型机,监控易通过IPMI和网页抓取数据的方式,监测包括服务器温度、风扇及电压等在内的关键指标,为…

Postfix+Dovecot+Roundcube开源邮件系统搭建系列1-2:系统搭建目标+MariaDB数据库配置(MySQL)

1. 系统搭建目标 通过本系列文章,最终可以部署一套提供如下服务的邮件系统: SMTP服务:由Postfix提供,监听25、465、587端口。POP3服务:由Dovecot提供,监听110、995端口。IMAP服务:由Dovecot提…

Java基础笔记(面试题)

一、Tomcat中为什么要使用自定义类加载器 Tomcat中可以放多个Java项目的jar文件,如果每个jar文件中都有一个User的类,那么User类在没有自定义类加载器的情况下是只能加载一次;想要加载多次,只能自定义类加载器 二、JDK、JRE、JVM…

项目管理进阶之RACI矩阵

前言 项目管理进阶系列续新篇。 RACI?这个是什么矩阵,有什么用途? 在项目管理过程中,如Team规模超5以上时,则有必要采用科学的管理方式,满足工作需要。否则可能事倍功半。 Q:什么是RACI矩阵 …

【简单介绍Gitea】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…

吴恩达大模型系列课程《Prompt Compression and Query Optimization》中文学习打开方式

Prompt Compression and Query Optimization GPT-4o详细中文注释的Colab观看视频1 浏览器下载插件2 打开官方视频 GPT-4o详细中文注释的Colab 中文注释链接:https://github.com/Czi24/Awesome-MLLM-LLM-Colab/tree/master/Courses/Prompt-Compression-and-Query-Op…

防溺水预警系统引领水域安全新篇章

一、系统概述 随着人们对水域活动的需求增加,溺水事故频发,给人们的生命安全带来了严重威胁。然而,如今,一项创新科技正在以强大的功能和无限的潜力引领着水域安全的新篇章。智能防溺水预警系统,作为一种集成了智能感知…

乐鑫ESP-IoT-Bridge方案简化设备智能联网通信,启明云端乐鑫代理商

随着物联网技术的快速发展,设备联网已成为实现智能化的关键一步。然而,不同设备之间的通信协议、接口等差异,使得设备联网变得复杂且困难。 乐鑫推出的ESP-IoT-Bridge联网方案,正是为了解决这一难题,为物联网场景下的…

抖音短视频seo矩阵系统源码(搭建技术开发分享)

#抖音矩阵系统源码开发 #短视频矩阵系统源码开发 #短视频seo源码开发 一、 抖音短视频seo矩阵系统源码开发,需要掌握以下技术: 网络编程:能够使用Python、Java或其他编程语言进行网络编程,比如使用爬虫技术从抖音平台获取数据。…

服务器的80和443端口关闭也能申请SSL证书

一、简介 在服务器的80和443端口关闭的情况下,确实可以申请SSL证书,但申请过程和方法会根据证书类型和验证方式的不同而有所差异。 通常如果是网站域名申请SSL证书,哪怕服务器的80、443端口都打不开,也可以通过DNS解析的方式来验…

设计模式-领域逻辑模式-领域模型(Domain Model)

例子 合并了行为和数据的领域的对象模型,如下图所示。 建立收入确认类 建立收入计算策略类 对象的传递过程

EasyExcel 学习之 导出 “WPS 表格在试图打开文件时遇到错误”

目录 1. 版本2. 现象2.1. Postman 文件下载成功且 WPS 可以正常打开2.2. VUE 下载成功但 WPS 无法打开 3. 原因:前端未指定 responseType4. 常见问题4.1. NoSuchMethodError4.1.1. org.apache.logging.log4j.LogBuilder org.apache.logging.log4j.Logger.atTrace()4.1.2. Could…