iOS - block

devtools/2025/1/20 0:20:03/

1. Block 的内存管理

// Block 的基本结构
struct Block_layout {void *isa;                // Block 的类型信息volatile int32_t flags;   // 标志位,包含引用计数等信息int32_t reserved;         // 保留字段void (*invoke)(void *, ...); // 函数指针,指向 Block 的实现struct Block_descriptor *descriptor; // Block 的描述信息
};// Block 的描述信息
struct Block_descriptor {unsigned long int reserved;     // 保留字段unsigned long int size;         // Block 的大小// 可选字段void (*copy)(void *dst, void *src);     // 复制辅助函数void (*dispose)(void *);               // 析构辅助函数
};

2. 弱引用处理

// 处理 Block 中的弱引用
void Block_object_assign(void *destAddr, const void *object, const int flags) {// 根据 flags 判断是强引用还是弱引用if (flags & BLOCK_FIELD_IS_WEAK) {// 处理弱引用weak_register_no_lock(&weak_table, object, destAddr);}
}// 清理 Block 中的引用
void Block_object_dispose(const void *object, const int flags) {if (flags & BLOCK_FIELD_IS_WEAK) {// 清理弱引用weak_unregister_no_lock(&weak_table, object, (void *)object);}
}

3. 引用计数管理

// Block 的引用计数管理
bool Block_tryRetain(const void *block) {struct Block_layout *layout = (struct Block_layout *)block;// 检查 Block 类型if (!layout->flags & BLOCK_NEEDS_FREE) {return true; // 全局或栈上的 Block}// 增加引用计数return OSAtomicIncrement32Barrier(&layout->flags) > 0;
}void Block_release(const void *block) {struct Block_layout *layout = (struct Block_layout *)block;// 减少引用计数if (OSAtomicDecrement32Barrier(&layout->flags) == 0) {(*layout->descriptor->dispose)(block);}
}

4. 内存管理优化

// Block 的内存优化
struct Block_byref {void *isa;                // 类型信息struct Block_byref *forwarding; // 指向自身或堆上的副本volatile int32_t flags;   // 标志位uint32_t size;            // Block 大小
};// 优化 Block 的复制
static void Block_copy_helper(Block_byref *dst, Block_byref *src) {// 1. 复制基本信息dst->forwarding = dst;  // 更新 forwarding 指针dst->size = src->size;// 2. 处理引用计数if (src->flags & BLOCK_HAS_COPY_DISPOSE) {// 调用 copy helper 函数(*src->byref_keep)(dst, src);}
}

5. 线程安全处理

// Block 的线程安全处理
static void Block_release_internal(void *block) {struct Block_layout *layout = (struct Block_layout *)block;// 原子操作处理引用计数if ((OSAtomicDecrement32Barrier(&layout->flags) & BLOCK_REFCOUNT_MASK) == 0) {if (layout->flags & BLOCK_NEEDS_FREE) {_Block_call_dispose_helper(block);_Block_destructInstance(block);}}
}

6. 注意事项

/*
Block 使用注意事项:1. 内存管理:- 注意循环引用- 正确使用 __weak 和 __strong- 注意 Block 的拷贝和释放2. 线程安全:- Block 的执行线程- 数据竞争问题- 同步访问共享数据3. 性能考虑:- Block 的大小- 拷贝开销- 内存使用
*/

总结要点:

1. 内存管理:

  • 引用计数机制
  • 弱引用处理
  • 拷贝和释放

2. 优化机制:

  • 内联优化
  • 内存布局优化
  • 引用计数优化

3. 线程安全:

  • 原子操作
  • 同步机制
  • 内存屏障

4. 注意事项:

  • 循环引用
  • 内存泄漏
  • 性能影响

http://www.ppmy.cn/devtools/151957.html

相关文章

一文了解汽车嵌入式软件开发Franca IDL 知识

本文主要是对 Franca IDL 的作用和设计意图进行解释说明,并且给出其他具有类似功能的 IDL 的对比。用实际的例子来说明核心设计理念,帮助理解设计意图。相比而言,其他 Franca IDL 文章更加注重参考手册的功能,本文试图探求Franca …

RPA编程实践:Electron实践开始

文章目录 前言闲话少叙,打开官网版本发布安装在 Windows 上安装在 macOS 上安装在 Linux (Ubuntu) 上安装 前言 上回说道,我们electron适合于熟悉web开发,但想要研发桌面应用的人。 但我觉得这个需求应该不是很多。 因为使用electron&#…

【学术会议论文投稿】Spring Boot实战:零基础打造你的Web应用新纪元

第七届人文教育与社会科学国际学术会议(ICHESS 2024)_艾思科蓝_学术一站式服务平台 更多学术会议请看:https://ais.cn/u/nuyAF3 目录 一、Spring Boot简介 1.1 Spring Boot的诞生背景 1.2 Spring Boot的核心特性 二、搭建开发环境 2.1…

03、Redis从入门到放弃 之 配置文件详解

redis常用配置文件信息:redis.conf redis-benchmark : redis压力测试 daemonize noRedis默认不是以守护进程的方式运行 port 6379指定Redis监听端口,默认端口为6379 bind 127.0.0.1绑定的主机地址 timeout 300客户端闲置多长时间后关闭连…

【ESP32】Arduino开发 | WiFi开发 | 基站模式 + AP扫描和AP连接例程

WiFi基站模式的详细讲解放在了ESP-IDF开发系列当中,点击栏目目录即可跳转找到。 1. API 1.1 初始化 wl_status_t begin(const char* ssid, const char *passphrase NULL, int32_t channel 0, const uint8_t* bssid NULL, bool connect true); ssid&#xff1…

Android SystemUI——CarSystemBar添加到窗口(十)

上一篇文章我们看到了车载状态栏 CarSystemBar 视图的创建流程,这里我们继续分析将车载状态栏添加到 Windows 窗口中。 一、添加状态栏到窗口 前面我们已经分析了构建视图对象容器和构建视图对象内容,接下来我们继续分析 attachNavBarWindows() 方法将视…

openharmony应用开发快速入门

开发准备 本文档适用于OpenHarmony应用开发的初学者。通过构建一个简单的具有页面跳转/返回功能的应用(如下图所示),快速了解工程目录的主要文件,熟悉OpenHarmony应用开发流程。 在开始之前,您需要了解有关OpenHarmon…

Oracle 表空间的使用与创建

Oracle 表空间的使用与创建(结合创建用户及权限管理) 在Oracle数据库中,表空间是数据库存储的逻辑单位,它用于存储数据库中的数据对象,如表、索引等。Oracle提供了不同类型的表空间(如普通表空间、大表空间…