iOS——Block签名
首先来看block结构体对象Block_layout
(等同于clang编译出来的__Block_byref_a_0
)
#define BLOCK_DESCRIPTOR_1 1
struct Block_descriptor_1 {uintptr_t reserved;uintptr_t size;
};#define BLOCK_DESCRIPTOR_2 1
struct Block_descriptor_2 {// requires BLOCK_HAS_COPY_DISPOSEBlockCopyFunction copy;BlockDisposeFunction dispose;
};#define BLOCK_DESCRIPTOR_3 1
struct Block_descriptor_3 {// requires BLOCK_HAS_SIGNATUREconst char *signature;const char *layout; // contents depend on BLOCK_HAS_EXTENDED_LAYOUT
};struct Block_layout {void *isa;volatile int32_t flags; // contains ref countint32_t reserved;BlockInvokeFunction invoke;struct Block_descriptor_1 *descriptor; //// imported variables
};
其中Block_layout
是基础的block结构空间,而部分block则拥有Block_descriptor_2
和Block_descriptor_3
结构,其中的flags
标识记录了一些信息
- 第1位:释放标记,一般常用BLOCK_NEEDS_FREE做位与操作,一同传入flags,告知该block可释放
- 第16位:存储引用计数的值,是一个可选参数
- 第24位:第16位是否有效的标志,程序根据它来决定是否增加火箭少女引用计数位的值
- 第25位:是否拥有拷贝辅助函数
- 第26位:是否拥有block析构函数
- 第27位:标志是否有垃圾回收
- 第28位:标志是否是全局block
- 第30位:与BLOCK_USE_START相对,判断当前block是否拥有一个签名,用于runtime时动态调用
但部分block则拥有Block_descriptor_2
和Block_descriptor_3
结构这句话又该怎么去理解呢?请看下面的解释
static struct Block_descriptor_2 * _Block_descriptor_2(struct Block_layout *aBlock)
{if (! (aBlock->flags & BLOCK_HAS_COPY_DISPOSE)) return NULL;uint8_t *desc = (uint8_t *)aBlock->descriptor;desc += sizeof(struct Block_descriptor_1);return (struct Block_descriptor_2 *)desc;
}static struct Block_descriptor_3 * _Block_descriptor_3(struct Block_layout *aBlock)
{if (! (aBlock->flags & BLOCK_HAS_SIGNATURE)) return NULL;uint8_t *desc = (uint8_t *)aBlock->descriptor;desc += sizeof(struct Block_descriptor_1);if (aBlock->flags & BLOCK_HAS_COPY_DISPOSE) {desc += sizeof(struct Block_descriptor_2);}return (struct Block_descriptor_3 *)desc;
}
- 如果
aBlock->flags & BLOCK_HAS_COPY_DISPOSE
满足,则_Block_descriptor_2
存在,反之则block没有_Block_descriptor_2
这个结构_Block_descriptor_2
可以通过Block_descriptor_1
内存偏移得到
- 同理,
aBlock->flags & BLOCK_HAS_SIGNATURE
满足,则_Block_descriptor_3
存在_Block_descriptor_3
可以通过Block_descriptor_2
内存偏移得到
决定这两个结构是否存在的绝对因素其实就是Block_layout
的flags
// Values for Block_layout->flags to describe block objects
enum {BLOCK_DEALLOCATING = (0x0001), // runtimeBLOCK_REFCOUNT_MASK = (0xfffe), // runtimeBLOCK_NEEDS_FREE = (1 << 24), // runtimeBLOCK_HAS_COPY_DISPOSE = (1 << 25), // compilerBLOCK_HAS_CTOR = (1 << 26), // compiler: helpers have C++ codeBLOCK_IS_GC = (1 << 27), // runtimeBLOCK_IS_GLOBAL = (1 << 28), // compilerBLOCK_USE_STRET = (1 << 29), // compiler: undefined if !BLOCK_HAS_SIGNATUREBLOCK_HAS_SIGNATURE = (1 << 30), // compilerBLOCK_HAS_EXTENDED_LAYOUT=(1 << 31) // compiler
};
接下来就用汇编来看看block中的签名
_ NSGlobalBlock__签名(_ Block_copy进入时)
方法签名在lldb调试中使用po命令,查看block对象的地址
通过方法签名,可以在运行时获取 Block 的参数和返回值类型,帮助程序在调用 Block 时正确地处理数据。
通过方法签名,你可以在运行时动态地调用不同的方法或函数,而不需要提前确定要调用的具体方法。
-
回调机制:方法签名使得你可以将方法或函数作为参数传递给其他方法或函数,从而实现回调机制。
-
反射机制:方法签名在反射机制中发挥重要作用,它允许程序在运行时获取方法的信息,如方法名称、参数个数、参数类型、返回值类型等。
-
适配器模式:在设计模式中,方法签名的使用有助于实现适配器模式,从而使不同接口的方法能够相互调用。
方法签名的含义可查看[[Type Encodings]] -
v
: 返回值是void
类型。 -
8@?
: 参数部分的编码。8
代表参数的个数。@
代表第一个参数是一个对象类型。?
代表第二个参数是一个 Block 类型。0
代表没有其他参数。
NSStackBlock
NSMallocBlock
相关文章:

iOS——Block签名
首先来看block结构体对象Block_layout(等同于clang编译出来的__Block_byref_a_0) #define BLOCK_DESCRIPTOR_1 1 struct Block_descriptor_1 {uintptr_t reserved;uintptr_t size; };#define BLOCK_DESCRIPTOR_2 1 struct Block_descriptor_2 {// requi…...
Flutter 图片选取及裁剪
在开发项目里修改用户头像的功能,涉及到图片选取及裁剪,基本实现步骤如下: 1、pubspec.yaml 添加 image_picker: ^1.0.1 image_cropper: ^4.0.1: dependencies:image_picker: ^1.0.1image_cropper: ^4.0.1flutter:sdk: flutter…...

C语言每日一题:11.《数据结构》链表分割。
题目一: 题目链接: 思路一:使用带头链表 1.构建两个新的带头链表,头节点不存储数据。 2.循环遍历原来的链表。 3.小于x的尾插到第一个链表。 4.大于等于x尾插到第二个链表。 5.进行链表合并,注意第二个链表的尾的下一…...
记一次Oracle归档日志异常增长问题的排查过程
Oracle归档日志是Oracle数据库的重要功能,用于将数据库的重做日志文件(Redo Log)保存到归档日志文件(Archive Log)中。归档日志的作用是提供数据库的备份和恢复功能,以及支持数据库的持续性和数据完整性。 …...
Java设计模式——类之间的关系
1.继承关系(泛化) 类与子类的关系,指一个类继承另外的一个类。 2.实现关系 一个类可以实现多个接口,实现所有接口的功能。 3.依赖关系 类B作为类A方法中的局部变量或者参数出现,表示A依赖B。 4.关联关系 类B作为类A中的成员变量出现&#…...
Dockerfile构建Redis镜像
建立工作目录 [rootlocalhost ~]# mkdir redis [rootlocalhost ~]# cd redis/ 编写Dockerfile文件 [rootlocalhost redis]# vim Dockerfile FROM centos:7 MAINTAINER dddd <dddd163.com> RUN yum -y install epel-release && yum -y install redis RUN sed -i …...

C高级DAY2
1.思维导图 2. 递归实现,输入一个数,输出这个数的每一位 递归实现,输入一个数,输出这个数的二进制c 写一个脚本,包含以下内容: 显示/etc/group文件中第五行的内容创建目录/home/ubuntu/copy切换工作路径到…...
Linux 服务管理
在Linux上,服务管理是指对系统中运行的服务进行启动、停止、重启、监控和配置的过程。以下是一些常用的Linux服务管理工具和命令: 1. systemctl:systemctl 是一个Linux系统服务管理工具,可以管理Systemd初始化系统的服务。常见的…...
问题记录 1 页面初始化触发el-form必填校验
bug: 先编辑table某条数据,然后关闭,再去新增的时候就会触发el-form必填校验, 网上搜了一下是因为 rules里触发的方式为change时,赋值数据的格式不一致导致触发校验, 最后也没找到正确的解决方法, 只能用很low方式去解决了 方案1. 把trigger改为 blur 失焦后触发 方案2. 初始化…...

后端整理(JVM、Redis、反射)
1. JVM 文章仅为自身笔记 详情查看一篇文章掌握整个JVM,JVM超详细解析!!! 1.1 什么是JVM jvm是Java虚拟机 1.2 Java文件的编译过程 程序员编写代码形成.java文件经过javac编译成.class文件再通过JVM的类加载器进入运行时数据…...

1. CUDA中的grid和block
1. CUDA中的grid和block基本的理解 Kernel: Kernel不是CPU,而是在GPU上运行的特殊函数。你可以把Kernel想象成GPU上并行执行的任务。当你从主机(CPU)调用Kernel时,它在GPU上启动,并在许多线程上并行运行。 Grid: 当你…...
宝存科技企业级固态硬盘解决方案助力企业应用性能提升
企业级固态硬盘解决方案的核心 企业级固态硬盘市场具有产品附加值高、同时进入门槛高的特征,由于国内外巨头和初创企业竞争依然激烈。想要在竞争中脱颖而出,根本还是要靠产品本身的品质和厂商实力。 企业级固态硬盘适用于各类企业应用场景 企业级固态硬盘…...
《练习100》31~35
题目31 # press any key to change color,do you want to try it. Please hurry up!# 第一种使用颜色配置输出 # 向终端输出彩色字符,色彩的设置由目标终端文字系统和转义字符控制,与具体的编程语言无关 # 参数名称 参数值 # 文字效果 0:终端…...
额外题目第4天|132 673 841 127 684 657
132 我发现困难题往往是在中等题的基础上再多了一步 分割最少次数的回文子串 这道题就是在之前动态规划法找回文子串 (leetcode第5题) 的基础上更多 这题还是用动规来写 思路参考代码随想录 dp数组表示的意义是从0到i最少切割的次数 递推公式是 取0到i中间值 j 如果从 j1到…...
HTTP 状态码的分类和含义
HTTP(Hypertext Transfer Protocol)状态码是由服务器向客户端传输的 HTTP 响应中的一个三位数字代码。它们提供了关于请求的处理状态和结果的信息。以下是一些常见的 HTTP 状态码及其含义: 1xx 信息响应:指示服务器已收到请求&…...
Linux Bridge(网桥)
Linux Bridge简介 Linux Bridge(Linux网桥)是一个软件层面的网络设备,用于在Linux系统中创建和管理网络桥接。它允许将多个物理或虚拟网络接口连接在一起,以创建一个共享相同网络段的网络。 下面是Linux Bridge的一些关键特点和…...
【数据结构】优先队列
优先队列 API初级实现使用堆实现由下至上的堆有序化(上浮)由上至下的堆有序化(下沉)插入和删除元素具体实现 很多情况下我们需要有序的处理输入的元素,但是又不需要输入的元素全部有序,或者不需要一次将它们…...

如何在 Ubuntu 22.04 下编译 StoneDB for MySQL 8.0 | StoneDB 使用教程 #1
作者:双飞(花名:小鱼) 杭州电子科技大学在读硕士 StoneDB 内核研发实习生 ❝ 大家好,我是 StoneDB 的实习生小鱼,目前正在做 StoneDB 8.0 内核升级相关的一些事情。刚开始接触数据库开发没多久,…...

AMEYA360:尼得科科宝旋转型DIP开关系列汇总
旋转型DIP开关 S-4000 电路:BCD(十进制) 代码格式:实码 安装类型:表面贴装 调整位置:顶部 可水洗:无 端子类型:J 引线, 鸥翼型 旋转型DIP开关 SA-7000 电路:BCD(十进制), BCH(十六进制) 代码格式…...

为什么感觉 C/C++ 不火了?
首先C和C是两个非常不一样的编程语言。 C语言在系统开发领域地位非常稳固,几乎没有替代产品。应用层开发近年来略微有被Rust取代的迹象。 C由于支持的编程范式过多,导致不同水平的人写出来的代码质量差异太大,这给软件的稳健性带来了很大的…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...