iOS - Runtime-isa详解(位域、union(共用体)、位运算)
文章目录
- iOS - Runtime-isa详解(位域、union(共用体)、位运算)
- 前言
- 1. `位域`介绍
- 1.1 思路
- 1.2 示例 - 结构体
- 1.3 示例 - union(共用体)
- 1.3.1 说明
- 1.4 结构体 对比 union(共用体)
- 2. arm64架构对isa的优化
- 2.1 位域内容
- nonpointer
- has_assoc
- has_cxx_dtor
- shiftcls
- magic
- weakly_referenced
- deallocating
- extra_rc
- has_sidetable_rc
- 2.2 Class、Meta-Class对象存储位置
- 3. 拓展
- 3.1 枚举值设计
- 3.1.1 案例
- 3.1.2 原理分析
iOS - Runtime-isa详解(位域、union(共用体)、位运算)
前言
本章主要了解Runtime相关内容,苹果对isa做了哪些优化,位域、union(共用体)又是如何运用的
- 要想学习Runtime,首先要了解它底层的一些常用数据结构,比如isa指针
- 在arm64架构之前,isa就是一个普通的指针,存储着
Class、Meta-Class对象的内存地址 - 从arm64架构开始,对isa进行了优化,变成了一个
共用体(union)结构,还使用位域来存储更多的信息
1. 位域介绍
利用好位域的话,可以使程序运行高效、节省内存,操作系统级别的东西很多都会使用
在IM系统的开发中,就使用了
位域来对数据进行优化,后续有时间再抽出案例聊聊。
欢迎点赞,收藏,加关注!,谢谢你!!
1.1 思路
假如ZSXPerson类需要3个BOOL类型的属性,这时候我们通常会直接使用@property声明3个属性,这时候系统会给我们生成 3个_开头的成员变量,3对get、set方法,所占据的内存也比较多
思路:BOOL 类型属性值要么 YES 要么 NO,使用字节中的一个位(0或者1)其实就能表示一个 BOOL 类型的属性值,一个字节就可以表示8个 BOOL 值
1.2 示例 - 结构体
ZSXPerson.h
@interface ZSXPerson : NSObject- (void)setTall:(BOOL)tall;- (BOOL)isTall;- (void)setRich:(BOOL)rich;- (BOOL)isRich;- (void)setHandsome:(BOOL)handsome;- (BOOL)isHandsome;@end
ZSXPerson.m
@interface ZSXPerson() {struct {char tall: 1;char rich: 1;char handsome: 1;} _tallRichHandsome;
}@end@implementation ZSXPerson- (void)setTall:(BOOL)tall {_tallRichHandsome.tall = tall;
}- (BOOL)isTall {return !!_tallRichHandsome.tall;
}- (void)setRich:(BOOL)rich {_tallRichHandsome.rich = rich;
}- (BOOL)isRich {return !!_tallRichHandsome.rich;
}- (void)setHandsome:(BOOL)handsome {_tallRichHandsome.handsome = handsome;
}- (BOOL)isHandsome {return !!_tallRichHandsome.handsome;
}@end
main.m
int main(int argc, const char * argv[]) {@autoreleasepool {ZSXPerson *person = [[ZSXPerson alloc] init];person.tall = NO;person.rich = YES;person.handsome = YES;NSLog(@"tall:%d rich:%d handsome:%d", person.isTall, person.isRich, person.isHandsome);}return 0;
}
运行结果:

1.3 示例 - union(共用体)
ZSXPerson.h
@interface ZSXPerson : NSObject- (void)setTall:(BOOL)tall;- (BOOL)isTall;- (void)setRich:(BOOL)rich;- (BOOL)isRich;- (void)setHandsome:(BOOL)handsome;- (BOOL)isHandsome;@end
ZSXPerson.h.m
#import "ZSXPerson.h"#define ZSXTallMask (1)
#define ZSXRichMask (1 << 1)
#define ZSXHandsomeMask (1 << 2)@interface ZSXPerson() {union {char bits;struct {char tall: 1;char rich: 1;char handsome: 1;};}_tallRichHandsome;
}@end@implementation ZSXPerson- (void)setTall:(BOOL)tall {if (tall) {_tallRichHandsome.bits |= ZSXTallMask;}else {_tallRichHandsome.bits &= ~ZSXTallMask;}
}- (BOOL)isTall {return !!(_tallRichHandsome.bits & ZSXTallMask);
}- (void)setRich:(BOOL)rich {if (rich) {_tallRichHandsome.bits |= ZSXRichMask;}else {_tallRichHandsome.bits &= ~ZSXRichMask;}
}- (BOOL)isRich {return !!(_tallRichHandsome.bits & ZSXRichMask);
}- (void)setHandsome:(BOOL)handsome {if (handsome) {_tallRichHandsome.bits |= ZSXHandsomeMask;}else {_tallRichHandsome.bits &= ~ZSXHandsomeMask;}
}- (BOOL)isHandsome {return !!(_tallRichHandsome.bits & ZSXHandsomeMask);
}@end
main.m
int main(int argc, const char * argv[]) {@autoreleasepool {ZSXPerson *person = [[ZSXPerson alloc] init];person.tall = NO;person.rich = YES;person.handsome = YES;NSLog(@"tall:%d rich:%d handsome:%d", person.isTall, person.isRich, person.isHandsome);}return 0;
}
运行结果:

1.3.1 说明

1.4 结构体 对比 union(共用体)

结构体的成员是各自占用各自所需大小共同体的内存大小取决于其中最大的成员的大小,所有成员共用这块内存

- 使用
共用体实际上还是通过位运算来控制每个属性所占位置 - 其中的
sturct目的是增加可读性,实际上不会影响属性所占位置
2. arm64架构对isa的优化
arm64架构对isa中,使用一个64位的共用体来存储更多的信息,通过位域的概念来表示各个存储的信息的存储位置。其中有33位拿来存储Class、Meta-Class的地址值


2.1 位域内容
nonpointer
- 0,代表普通的指针,存储着Class、Meta-Class对象的内存地址
- 1,代表优化过,使用位域存储更多的信息
has_assoc
- 是否有设置过关联对象,如果没有,释放时会更快
has_cxx_dtor
- 是否有C++的析构函数(.cxx_destruct),如果没有,释放时会更快
shiftcls
- 存储着Class、Meta-Class对象的内存地址信息
magic
- 用于在调试时分辨对象是否未完成初始化
weakly_referenced
- 是否有被弱引用指向过,如果没有,释放时会更快
deallocating
- 对象是否正在释放
extra_rc
- 里面存储的值是引用计数器减1
has_sidetable_rc
- 引用计数器是否过大无法存储在isa中
- 如果为1,那么引用计数会存储在一个叫SideTable的类的属性中
2.2 Class、Meta-Class对象存储位置
Class、Meta-Class对象存储在shiftcls,从上图可知shiftcls是从第4位开始,连续33位
isa的掩码:define ISA_MASK 0x0000000ffffffff8ULL
将掩码转为二进制查看

它表示的就是从第4位开始,连续33位,通过这个掩码,就可以将Class、Meta-Class的地址值取出来
Class、Meta-Class的地址值后三位永远是 0。因为他的掩码左右边3位是 0,&运算后一定是 0
3. 拓展
3.1 枚举值设计
在iOS中,系统的一些API可以使用|传入多个枚举值,比如:
self.view.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
原理就是使用位域设计枚举值,然后通过位运算来取值
3.1.1 案例
我们也自己来设计一个这样的枚举
定义枚举:
typedef NS_OPTIONS(NSUInteger, ZSXOptions) {ZSXOptions1 = 1 << 0, // 0b00000001ZSXOptions2 = 1 << 1, // 0b00000010ZSXOptions3 = 1 << 2, // 0b00000100ZSXOptions4 = 1 << 3, // 0b00001000ZSXOptions5 = 1 << 4, // 0b00010000
};
设置值方法:
- (void)setOptions:(ZSXOptions)options {if (options & ZSXOptions1) {NSLog(@"包含了ZSXOptions1");}if (options & ZSXOptions2) {NSLog(@"包含了ZSXOptions2");}if (options & ZSXOptions3) {NSLog(@"包含了ZSXOptions3");}if (options & ZSXOptions4) {NSLog(@"包含了ZSXOptions4");}if (options & ZSXOptions5) {NSLog(@"包含了ZSXOptions5");}
}
使用:
[self setOptions:ZSXOptions1 | ZSXOptions3 | ZSXOptions5];
打印如下:

此时我们已经实现了一个可以传入多个枚举值的接口
3.1.2 原理分析
/**0b000000010b000001000b00010000----------------- | 运算(设置值)0b000101010b00000001----------------- & 运算(取值)0b00000001 为 true*/
@oubijiexi
相关文章:
iOS - Runtime-isa详解(位域、union(共用体)、位运算)
文章目录 iOS - Runtime-isa详解(位域、union(共用体)、位运算)前言1. 位域介绍1.1 思路1.2 示例 - 结构体1.3 示例 - union(共用体)1.3.1 说明 1.4 结构体 对比 union(共用体) 2. a…...
使用VSCode搭建Vue 3开发环境
使用VSCode搭建Vue 3开发环境 Vue 3是一种流行的前端JavaScript框架,它提供了响应式的数据绑定和组合式的API。Visual Studio Code(VSCode)是一个轻量级但功能强大的源代码编辑器,支持多种语言开发。本文将引导您完成使用VSCode搭建Vue 3开发环境的步骤。 1. 下载和安装V…...
深度学习中的模型蒸馏技术:实现流程、作用及实践案例
在深度学习领域,模型压缩与部署是一项重要的研究课题,而模型蒸馏便是其中一种有效的方法。 模型蒸馏(Model Distillation)最初由Hinton等人在2015年提出,其核心思想是通过知识迁移的方式,将一个复杂的大模型…...
Java服务运行在Linux----维护常用命令
想起来哪些再添加上去 查看Java程序进程 jps -l 查出进程后根据pid 查询程序所在目录 pwdx 31313 根据端口查找PID 根据pid杀死程序 kill -p 31313 查看目录下所有包含9527的文件 grep -rn 9527 查看磁盘空间 查找文件名"nginx"文件或模糊查找"*nginx*&quo…...
夜晚水闸3D可视化:科技魔法点亮水利新纪元
在宁静的夜晚,当城市的霓虹灯逐渐暗淡,你是否曾想过,那些默默守护着城市安全的水闸,在科技的魔力下,正焕发出别样的光彩?今天,就让我们一起走进夜晚水闸3D模型,感受科技为水利带来的…...
从零开始的软件开发实战:互联网医院APP搭建详解
今天,笔者将以“从零开始的软件开发实战:互联网医院APP搭建详解”为主题,深入探讨互联网医院APP的开发过程和关键技术。 第一步:需求分析和规划 互联网医院APP的主要功能包括在线挂号、医生预约、医疗咨询、健康档案管理等。我们…...
【深度学习】YOLO检测器的发展历程
YOLO检测器的发展历程 YOLO(You Only Look Once)检测器是一种流行的实时对象检测系统,以其速度和准确性而闻名。自2016年首次推出以来,YOLO已经成为计算机视觉领域的一个重要里程碑。在本博客中,我们将探讨YOLO检测器…...
C语言--编译和链接
1.翻译环境 计算机能够执行二进制指令,我们的电脑不会直接执行C语言代码,编译器把代码转换成二进制的指令; 我们在VS上面写下printf("hello world");这行代码的时候,经过翻译环境,生成可执行的exe文件&…...
实现使用C#代码完成wifi的切换和连接功能
实现使用C#代码完成wifi的切换和连接功能 代码如下: namespace Wifi连接器 {public partial class Form1 : Form{private List<Wlan.WlanAvailableNetwork> NetWorkList new List<Wlan.WlanAvailableNetwork>();private WlanClient.WlanInterface Wla…...
Mac添加和关闭开机应用
文章目录 mac添加和关闭开机应用添加开机应用删除/查看 mac添加和关闭开机应用 添加开机应用 删除/查看 打开:系统设置–》通用–》登录项–》查看登录时打开列表 选中打开项目,点击“-”符号...
QT QInputDialog弹出消息框用法
使用QInputDialog类的静态方法来弹出对话框获取用户输入,缺点是不能自定义按钮的文字,默认为OK和Cancel: int main(int argc, char *argv[]) {QApplication a(argc, argv);bool isOK;QString text QInputDialog::getText(NULL, "Input …...
Unity3d使用Jenkins自动化打包(Windows)(一)
文章目录 前言一、安装JDK二、安装Jenkins三、Jenkins插件安装和使用基础操作 实战一基础操作 实战二 四、离线安装总结 前言 本篇旨在介绍基础的安装和操作流程,只需完成一次即可。后面的篇章将深入探讨如何利用Jenkins为Unity项目进行打包。 一、安装JDK 1、进入…...
HarmonyOS 应用开发之Want的定义与用途
Want 是一种对象,用于在应用组件之间传递信息。 其中,一种常见的使用场景是作为 startAbility() 方法的参数。例如,当UIAbilityA需要启动UIAbilityB并向UIAbilityB传递一些数据时,可以使用Want作为一个载体,将数据传递…...
enscan自动化主域名信息收集
enscan下载 Releases wgpsec/ENScan_GO (github.com) 能查的分类 实操: 首先打开linux 的虚拟机、 然后把下面这个粘贴到虚拟机中 解压后打开命令行 初始化 ./enscan-0.0.16-linux-amd64 -v 命令参数如下 oppo信息收集 运行下面代码时 先去配置文件把coo…...
分享全栈开发医疗小程序 -带源码课件(课件无解压密码),自行速度保存
课程介绍 分享全栈开发医疗小程序 -带源码课件(课件无解压密码),自行速度保存!看到好多坛友都在求SpringBoot2.X Vue UniAPP,全栈开发医疗小程序 - 带源码课件,我看了一下,要么链接过期&…...
基于YOLOv8与ByteTrack实现多目标跟踪——算法原理与代码实践
概述 在目标检测中,有许多经算法如Faster RCNN、SSD和YOLO的各种版本,这些算法利用深度学习技术,特别是卷积神经网络(CNN),能够高效地在图像中定位和识别不同类别的目标。Faster RCNN是一种基于区域提议的…...
C语言——函数练习程序
1.从终端接收一个数,封装一个函数判断该数是否为素数 #include <stdio.h>int pri(int num) {int i 0;for (i 2; i < num; i){if (num % i 0){return 0;break;}}if (i num-1){return 1;} }int main(void) {int num 0;int ret 0;scanf("%d", &num);…...
ssh 启动 docker 中 app, docker logs 无日志
ssh 启动 app, 标准输出被重定向 ssh 客户端,而不是 docker 容器的标准输出。只需要在启动时把app 标准输出重定向到 docker标准输出。 测试如下: 1.启动 docker docker run -it -p 60022:22 --name test test:v4 bash -c "service ssh restart;…...
WPF---1.入门学习
🎈个人主页:靓仔很忙i 💻B 站主页:👉B站👈 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:WPF 🤝希望本文对您有所裨益,如有不足之处…...
Vue3 + Vite + TS + Element-Plus + Pinia项目(5)对axios进行封装
1、在src文件夹下新建config文件夹后,新建baseURL.ts文件,用来配置http主链接 2、在src文件夹下新建http文件夹后,新建request.ts文件,内容如下 import axios from "axios" import { ElMessage } from element-plus im…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
