[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.rhkb.cn/news/378881.html

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

相关文章

新华三H3CNE网络工程师认证—VLAN使用场景与原理

通过华三的技术原理与VLAN配置来学习,首先介绍VLAN,然后介绍VLAN的基本原理,最后介绍VLAN的基本配置。 一、传统以太网问题 在传统网络中,交换机的数量足够多就会出现问题,广播域变得很大,分割广播域需要…

R语言优雅的把数据基线表(表一)导出到word

基线表(Baseline Table)是医学研究中常用的一种数据表格,用于在研究开始时呈现参与者的初始特征和状态。这些特征通常包括人口统计学数据、健康状况和疾病史、临床指标、实验室检测、生活方式、社会经济等。 本人在既往文章《scitb包1.6版本发…

C++客户端Qt开发——QT初识

二、QT初识 1.helloworld示例 ①图形化的方式,在界面上创建出一个控件,显示helloworld 右侧通过树形结构,就会显示出当前界面上有哪些控件 此时.ui文件已发生变化 qmake就会在编译项目的时候,基于这个内容,生成一段C…

35.UART(通用异步收发传输器)-RS232(2)

(1)RS232接收模块visio框图: (2)接收模块Verilog代码编写: /* 常见波特率: 4800、9600、14400、115200 在系统时钟为50MHz时,对应计数为: (1/4800) * 10^9 /20 -1 10416 …

链接追踪系列-10.mall-swarm微服务运行并整合elk-上一篇的番外

因为上一篇没对微服务代码很详细地说明,所以在此借花献佛,使用开源的微服务代码去说明如何去做链路追踪。 项目是开源项目,fork到github以及gitee中,然后拉取到本地 后端代码: https://gitee.com/jelex/mall-swarm.gi…

微软研究人员为电子表格应用开发了专用人工智能LLM

微软的 Copilot 生成式人工智能助手现已成为该公司许多软件应用程序的一部分。其中包括 Excel 电子表格应用程序,用户可以在其中输入文本提示来帮助处理某些选项。微软的一组研究人员一直在研究一种新的人工智能大型语言模型,这种模型是专门为 Excel、Go…

BiLSTM 实现股票多变量时间序列预测(PyTorch版)

前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对…

算法题目整合

文章目录 121. 小红的区间翻转142. 两个字符串的最小 ASCII 删除总和143. 最长同值路径139.完美数140. 可爱串141. 好二叉树 121. 小红的区间翻转 小红拿到了两个长度为 n 的数组 a 和 b,她仅可以执行一次以下翻转操作:选择a数组中的一个区间[i, j]&…

SpringBoot集成MQTT实现交互服务通信

引言 本文是springboot集成mqtt的一个实战案例。 gitee代码库地址:源码地址 一、什么是MQTT MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe&…

教大模型学数学,总共分几步?

大模型那么聪明,为什么数学题总是做不对、做不会? 从答高考数学卷难及格到普通数字比大小出错,大模型总算让大家觉得并非“无所不能”。这一方面让普通人开心,毕竟讲到AI取代人类看起来为时尚早,而另一方面&#xff0…

Autosar RTE配置-Assembly和Delegation的使用-基于ETAS软件

文章目录 前言Assembly和Delegation的含义Delegation的使用Assembly的使用总结 前言 RTE中的Compostion内部的SWC之间的连接使用Assembly Connector进行连接。这样的连接一般都是一个SWC的Pport对应另一个SWC的Rport。而Autosar软件中往往不只一个Composition(一般可以以核的数…

Android Toast

Toast Toast是Android常用的简单控件,主要用来进行简短的信息提示,如图1所示。 图1 Toast效果图 Toast的基本用法很简单,不需要设置layout,只需要在程序中调用即可。Toast调用makeText()方法设置需要显示的界面、显示的内容、显…

【计算机网络】学习指南及导论

个人主页:【😊个人主页】 系列专栏:【❤️计算机网络】 文章目录 前言我们为什么要学计算机网络?计算机网络概述计算机网络的分类按交换技术分类按使用者分类按传输介质分类按覆盖网络分类按覆盖网络分类 局域网的连接方式有线连接…

Lua基础知识入门

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

河南萌新联赛2024第(一)场:河南农业大学

A.造数 题目: 链接:https://ac.nowcoder.com/acm/contest/86639/A 思路: 签到题,特判如果n0,输出0,如果n1或2,输出1;while循环,首先如果n%2!0,那么s&…

基于Web的特产美食销售系统的设计与实现

💗博主介绍💗:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示:文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

Spring Web MVC(常用的注解@RequestMapping,@RequestParam,@RequestBody等)

一、Spring MVC spring的启动类 启动类是看这个 SpringBootApplication 注解,而不是 类的名字 这个注解在哪,哪个类就是启动类 1.MVC思想 举例 二、Spring MVC mvc 是一种思想,而spring mvc是对mvc思想的一种实现。全称是 spring web mvc…

笔记 2 : 课本第 3 章开始,记录 arm 的汇编指令的格式

(13) 介绍 arm 中的第一个汇编指令的用法 mov : (14)立即数的概念: (15) 汇编中的移位写法: 举例 : (16) 学习一个新的指令 cmp &a…

【大型实战】企业网络实验(华为核心交换、ESXI7.0vmware虚拟机、DHCP中继、服务端网络及用户端网络配置)

需求 实验 vmware网络配置(企业内部一般为ESXI) 这样服务器虚拟机使用192.168.200.X网段才能与用户侧互通 vmware虚拟机配置(DHCP服务器网络配置) 打开网络管理页面 nmtui重置一下网络连接(重启网卡) …

ubuntu24.04 linux bcm94352hmb 无线网卡(带蓝牙功能)无法连接蓝牙设备的解决办法

ubuntu24.04 linux bcm94352hmb 无线网卡(带蓝牙功能)无法连接蓝牙设备的解决办法 问题描述 小本是自己换装的bcm94352hmb,现在跑不动黑苹果了,换装ubuntu,该网卡在黑苹果上和windows上都能正常工作,到了…