iOS - Runtime-isa详解(位域、union(共用体)、位运算)

【C语言】第六课 联合体(Union)和位域(Bit-field) 使用unionint i;// 整型成员float f;// 浮点成员// 字符数组成员内存共享:所有成员共享同一段内存,联合体的大小由其最大成员决定(例如上例中约为20字节,取决于和系统对齐规则)。访问成员:使用点操作符访问联合体变量的成员,若通过指针访问则使用箭头操作符->。// 此时联合体存储的是整数// 写入浮点数,覆盖之前的整数值初始化:联合体初始化时只能初始化其第一个成员。// 正确:初始化第一个成员i// C99后允许指定初始化成员,但仍需注意覆盖。 阅读详情

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, // 0b00000001
    ZSXOptions2                 = 1 << 1, // 0b00000010
    ZSXOptions3                 = 1 << 2, // 0b00000100
    ZSXOptions4                 = 1 << 3, // 0b00001000
    ZSXOptions5                 = 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 原理分析

/**
 0b00000001
 0b00000100
 0b00010000
 ----------------- | 运算(设置值)
 0b00010101
 
 0b00000001
 ----------------- & 运算(取值)
 0b00000001    为 true
 */

@oubijiexi

iOS对象本质及isa 通过底层c/c++源码,我们可以来探究iOS对象的本质和isa。 阅读详情

相关推荐

Python typing实战:从函数签名到CI门禁的类型契约工程

Python作为动态语言,天然缺乏编译期类型约束,导致运行时隐性错误频发,如None穿透、字符串误参与数值计算等。typing module通过静态类型提示机制,在不改变运行行为的前提下,构建可验证的接口契约。其核心价值在于提升协作确定性与故障拦截前置性——借助mypy等检查器,在编码阶段即发现类型不匹配,而非等待线上报错。典型应用场景包括API参数校验、数据管道字段保障、跨模块调用契约定义等。本文聚焦真实项目落地路径,详解函数签名优先策略、TypedDict结构化字典、Protocol鸭子类型协议及渐进式

a1311010193的博客 366

【iOS】isa指针的结构(位域)

isa指针的结构(位域)

cheng_lin0201的博客 1508

iOS之深入解析对象isa的底层原理

一、isa 简介 alloc初始化时不仅创建了对象并且分配内存,同时初始化 isa 指针属性。Objective-C 对象在底层本质上是结构体,所有的对象里面都会包含有一个 isa ,isa 的定义是一个联合体 isa_t,isa_t 包含了当前对象指向类的信息。 isa 是一个联合体,而这其实是从内存管理层面来设计的,因为联合体是所有成员共享一个内存,联合体内存的大小取决于内部成员内存大小最大的那个元素,对于 isa 指针来说,就不用额外声明很多的属性,直接在内部的 ISA_BITFIELD 保存信息。

╰つ栺尖篴夢ゞ 1万+

iOS -- isa指针

isa指针

cyberjack的博客 2653

DRM驱动代码分析:展频 跳频

DRM驱动代码分析:展频 跳频

yuuu_cheer的博客 2673

【小贪】万字长文介绍因果推断和增益模型

本文首先从一个实例出发阐述了因果性不等于相关性,进而引出因果推断和增益模型。然后简单介绍了因果推断的基础内容,并介绍了主要的三类增益模型:元学习、增益直接建模、表示学习,每一类模型都简要介绍了其经典模型。之后介绍了增益模型的评价指标,包括uplift bins、uplift curve和qini曲线。增益模型实际上是一大类模型框架,本质上可以用传统响应模型或其他机器学习模型嵌入增益模型的框架,但是预测结果并不是一个概率,模型评价方式也有变化。训练样本收集增益模型建模强依赖于ab实验,数据要求很高。

打瞌睡_的博客 2506

Runtime学习基础之isa指针(终结篇)

如果您在看这篇博客时候,还没看过我上一篇博客,需要您去耐心的看一下,有助于更快更好的理解这篇博客的内容Runtime学习基础之isa指针 好,我们继续上篇博客继续说:我们先用结构体解决这个问题 ,请看下面的代码 这里我们定义一个结构体,里面存储3个参数,我们看一下结果能不能解决这个问题:请看下面的代码截图 这个明显是解决了情况,大家可以尝试其他情况,接下来,我们就引入今天最重要的模块,就是共同体union 首先我们先看我们这个需求怎么用共用体union来解决,这里我直接写结果,等会再.

Lucky_Deng的博客 453

论文代码复现 | 无人机与卡车联合配送(Python+Gurobi)(The flying sidekick traveling salesman problem)

无人机配送-代码复现The flying sidekick traveling salesman problem-Part 1文献笔记:(无人机配送-代码复现)The flying sidekick traveling salesman problem-Part 1摘要论文主要图标摘录数值实验算例结果参考文献 文献笔记:(无人机配送-代码复现)The flying sidekick traveling salesman problem-Part 1 摘要 Once limited to the milit

HsinglukLiu的博客 3万+

Runtime中的 isa 结构体

原文链接 有一定经验的iOS开发者,或多或少的都听过Runtime。Runtime,也就是运行时,是Objective-C语言的特性之一。日常开发中,可能直接和Runtime打交道的机会不多。然而,"发消息"、"消息转发"这些名词开发者应该经常听到,这些名词所用到的技术基础就是Runtime。了解Runtime,有助于开发者深入理解Objective-C这门语言。 在具体了解Runtime之前,先...

weixin_33976072的博客 443

硅谷刷屏的ClawdBot,让Mac mini卖爆了!创始人爆料:一人开发、100% AI 写代码

这两天,个人 AI 助手 ClawdBot 席卷硅谷,国内外社交平台上全是关于它的讨论。 在试用后,网友们纷纷给出了很高的评价。“它是迄今为止最伟大的 AI 应用,相当于你 24 小时全天候专属 AI 员工。”Creator Buddy 创始人兼 CEO Alex Finn 盛赞道,“这就是他们 (Anthropic) 希望 Claude Cowork 呈现的样子。”

技术引领业务创新 1583

Android布局基础与UI设计入门:打造精美应用界面

恭喜你!现在你已经掌握了Android UI开发的基础知识,包括各种布局类型、常用控件的使用以及一些UI优化技巧。这些知识将帮助你设计出既美观又实用的Android应用界面。

m0_65382359的博客 2056

iOS之runtime详解api(二)

在上一篇我们讲解了runtime里面关于类和分类的函数,那么,我们这一篇就讲解下关于Method的那些函数。 3.objc_method or Method objc_method或者Method(这两个其实是同一个)这个结构体在runtime.h文件里并没有详细的告诉我们其中的成员变量,这个在这个阶段也不是很重要,后面我将会在分析runtime源码的时候,再去分析这个结构体,现在我们只需知道这个...

weixin_34364135的博客 194

基于 STM32 的智慧图书馆智能控制系统设计与实现

智慧图书馆智能控制系统集成环境调控、安全监控、借阅管理与信息推送功能,通过 STM32 主控芯片联动传感器、执行器及云平台,实现图书馆智能化管理。系统架构分为感知层(传感器)、控制层(STM32 主控)、执行层(继电器 / 显示屏)及云端层(数据交互),支持温度自动调节、灯光自控、火情安防监控、天气推送及 RFID 借还书管理。本系统通过 STM32 实现多传感器融合与设备控制,结合 RFID 与云平台技术,构建了集环境智能调控、安全监控、便捷借阅于一体的智慧图书馆解决方案。

weixin_42300449的博客 2200

iOS基础---OC runtime篇一之基本概念

OC的runtime是基于C语言实现的objective-C 的动态运行时机制,是iOS开发者最基础的知识,虽然互联网上相关的介绍多如牛毛,但是这种最基础的机制,每个开发者都需要有自己的理解与整理。 基本概念 第一、struct和union 由于runtime是基于C实现的,里面有大量的C预研数据结构,如果对C语言不太熟悉,理解起来未免费劲。所以,这里首先需要搞清楚这两个概念: struc...

u012413955的博客 507

【银河麒麟V10】【桌面】【服务器】系统启动问题

1、如果之前运行好好的,重启后系统报错,一般80%是因为fstab的问题,回想下之前有没有添加过外接存储,修改过/etc/fstab,如果是的话一般是因为存储异常(比如网络存储无法连接,本地存储路径变化)导致系统开机自检失败,导致无法正常启动; 处理方式:进入单用户(单用户进入的几种方式上面有专门文章介绍),修改/etc/fstab,将新增的内容暂时注释掉,然后重启系统,能正常进入系统后再分析失败原因。 ...

桂安俊@KylinOS 3万+

YOLO26涨点改进 | 全网独家创新、检测头Head改进篇 | AAAI 2026 | 使用StripConvHead改进YOLO26的检测头,处理小目标、遮挡小目标检测有效涨点,助力高效发论文

🔥本文给大家介绍使用StripConv条形卷积改进 YOLO26的检测头,可以显著提高模型在高纵横比物体检测、目标定位和多尺度物体检测方面的表现。StripConv条形卷积能够更有效地捕捉细长物体的特征,提升定位精度,并通过简化卷积核设计减少计算冗余,优化计算效率。此外,该改进增强了 YOLO26对复杂场景和实时任务的适应能力,特别适用于遥感图像目标检测、小目标检测等领域。具体怎么使用请看全文。摘要:随着遥感物体检测的快速发展,检测高纵横比物体仍然是一个挑战性问题。

Ai缝合怪、助力小伙伴高效发论文 268

移动端应用开发:controlnet-union-sdxl-1.0 ONNX模型转换教程

controlnet-union-sdxl-1.0是一款功能强大的AI绘图模型,本教程将详细介绍如何将其转换为ONNX格式,以便在移动端应用中高效部署和运行。通过本教程,你将快速掌握模型转换的关键步骤和实用技巧,让AI绘图能力在移动设备上得以实现。 ## 准备工作:环境搭建与依赖安装 在进行模型转换之前,需要确保你的开发环境已经安装了必要的工具和库。首先,克隆项目仓库到本地: ```bash

gitblog_00417的博客 521

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

WWDC 2017 Feature 102 Platforms State of the Union

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33845477的博客 126

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

微软技术周报·2026-08-24~2026-08-31——.NET11 Preview7最后一个预览版、AI Agent基础设施全面走向GA与治理化

微软技术周报:.NET 11功能冻结前最后一版Preview 7发布,C#带标签break、union模式改进,Runtime Async性能飞跃;AI Agent全面GA与治理化(Agent Plugins 1.0、VS 2026组织级Agent、Copilot Studio迁移Entra Agent ID);Windows 11 26H2进入Release Preview,预计9月底推送。

海盗Sharp的博客 967

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

iOS方法返回值和参数对应的Type Encodings

iOS方法返回值和参数对应的Type Encodings

dengbin9009的专栏 1604

微软技术周报 · 2026-08-11~2026-08-18

微软本周技术动态聚焦两大方向:AI体验整合与安全更新。AI方面,Copilot统一入口copilot.cloud.microsoft上线,Foundry Agent框架GA,MAI模型家族完成5线整合;开发者工具上,C# 14正式支持扩展成员、field关键字等特性,.NET 11 Preview 7优化异步分层编译和WASM支持。安全侧发布8月补丁日,修复421个CVE(含1个Lazarus组织利用的零日漏洞)。其他亮点包括VS Code接入MAI-Voice、Power Platform现代控件GA、T

海盗Sharp的博客 824

RapidOCR异构计算架构解析:多引擎融合下的文字识别性能突破

在实时支付验证、文档数字化和智能监控等场景中,OCR技术的响应延迟直接影响用户体验和系统效率。传统OCR方案往往受限于单一推理引擎,难以在不同硬件平台上发挥最佳性能。RapidOCR通过创新的异构计算架构,将文字识别从毫秒级优化至微秒级,实现了从算法设计到工程部署的全栈性能突破。 ## 架构创新:统一接口下的多引擎融合策略 ### 核心设计理念:抽象与适配 RapidOCR的核心创新在于其统一

gitblog_00626的博客 412

深入解析Mach-O动态库加载机制与LC_ID_DYLIB

动态链接库(Dynamic Library)是现代操作系统的核心组件,通过内存共享和模块化设计显著提升软件性能与维护性。Mach-O作为macOS/iOS系统的可执行文件格式,其动态库加载机制涉及路径解析、版本控制和符号绑定等关键技术。LC_ID_DYLIB作为Mach-O的关键加载命令,定义了动态库的身份标识、安装路径和版本信息,直接影响dyld(动态链接器)的加载行为。通过@executable_path、@loader_path和@rpath等路径变量,开发者可以构建灵活的库依赖关系。掌握otool、

weixin_30323631的博客 379

ios开发数据库版本迁移手动更新迭代和自动更新迭代艺术(-)

demo 地址https://github.com/PureLovePeter/DataCache好用的话 star star star 数据库版本迁移顾名思义就是在原有的数据库中更新数据库,数据库中的数据保持不变对表的增、删、该、查。 数据持久化存储: plist文件(属性列表) preference(偏好设置) NSKeyedArchiver(归...

aiqian1239的博客 247

YOLOv5代码架构解析与工程实践指南

目标检测作为计算机视觉的核心任务,其核心原理是通过卷积神经网络提取特征并预测物体位置与类别。YOLOv5作为当前工业界最流行的单阶段检测器,凭借其卓越的速度-精度平衡和模块化设计成为首选框架。该架构采用PyTorch实现,包含模型定义、数据增强、损失函数等完整组件,特别在工程实践上集成了混合精度训练、模型轻量化等前沿技术。通过分析其代码结构可以发现,YOLOv5通过优化后的CIoU损失函数提升检测精度,配合NMS后处理实现高效推理。在实际部署中,模型支持ONNX、TensorRT等多种格式转换,适用于嵌入式

weixin_34364071的博客 387

东华上机DAY17项目:数据结构与算法实战指南

数据结构与算法是计算机科学的核心基础,其原理涉及数据的组织、存储和高效处理。通过栈、队列、动态规划等技术手段,可以解决字符串解码、背包问题等经典工程问题。在实际应用场景中,如图论算法能有效处理课程安排、任务调度等复杂关系问题。本文以东华大学DAY17上机项目为例,详解字符串处理、动态规划、拓扑排序等高频考点,提供可复用的C++/Python解题模板,并分享调试技巧与性能优化经验,帮助学生提升算法竞赛和工程实践能力。

weixin_34109408的博客 320
上一篇: OC对象 - Block解决循环引用
下一篇: iOS - Runtime - Class的结构
aiousee
博客等级 码龄14年 540粉丝 45原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值