iOS - 弱引用表(Weak Reference Table)
1. 基本数据结构
// 弱引用表的基本结构
struct weak_table_t {weak_entry_t *weak_entries; // 保存所有的弱引用对象size_t num_entries; // 当前存储的弱引用数量uintptr_t mask; // 哈希表大小掩码uintptr_t max_hash_displacement; // 最大哈希偏移值
};// 单个对象的弱引用信息
struct weak_entry_t {DisguisedPtr<objc_object> referent; // 被引用的对象union {struct {weak_referrer_t *referrers; // 动态数组uintptr_t out_of_line : 1; // 是否使用动态数组uintptr_t num_refs : PTR_MINUS_1; // 引用计数uintptr_t mask; // 容量掩码uintptr_t max_hash_displacement;};struct {// 内联存储,用于优化少量弱引用的情况weak_referrer_t inline_referrers[WEAK_INLINE_COUNT];};};
};
2. 核心操作
2.1 添加弱引用
id weak_register_no_lock(weak_table_t *weak_table, id referent, id *referrer, bool crashIfDeallocating) {// 1. 查找或创建 entryweak_entry_t *entry = weak_entry_for_referent(weak_table, referent);if (entry == nil) {entry = new_entry_for_referent(referent, referrer);weak_entry_insert(weak_table, entry);}// 2. 添加弱引用append_referrer(entry, referrer);return referent;
}
2.2 移除弱引用
void weak_unregister_no_lock(weak_table_t *weak_table, id referent, id *referrer) {weak_entry_t *entry = weak_entry_for_referent(weak_table, referent);if (entry == nil) return;// 移除引用remove_referrer(entry, referrer);// 如果 entry 为空,则移除if (entry->out_of_line && entry->num_refs == 0) {weak_entry_remove(weak_table, entry);}
}
3. 存储优化
3.1 内联存储
#define WEAK_INLINE_COUNT 4struct weak_entry_t {union {// 当弱引用数量少时,使用内联数组struct {weak_referrer_t inline_referrers[WEAK_INLINE_COUNT];};// 当弱引用数量多时,使用动态数组struct {weak_referrer_t *referrers;uintptr_t out_of_line : 1;};};
};
3.2 动态扩展
static void grow_refs_and_insert(weak_entry_t *entry, objc_object **new_referrer) {assert(entry->out_of_line());size_t old_size = TABLE_SIZE(entry);size_t new_size = old_size ? old_size * 2 : 8;// 分配新空间weak_referrer_t *new_refs = (weak_referrer_t *)calloc(new_size, sizeof(weak_referrer_t));// 迁移数据for (size_t i = 0; i < old_size; i++) {weak_referrer_t oldref = entry->referrers[i];if (oldref) {weak_referrer_t *new_ref = new_refs + hash_pointer(oldref);*new_ref = oldref;}}
}
4. 线程安全
4.1 锁保护
struct SideTable {spinlock_t slock; // 自旋锁RefcountMap refcnts;weak_table_t weak_table;void lock() { slock.lock(); }void unlock() { slock.unlock(); }
};// 使用示例
void weak_register_no_lock(weak_table_t *weak_table, id referent) {SideTable& table = SideTables()[referent];table.lock();// 操作 weak_tabletable.unlock();
}
4.2 原子操作
bool weak_entry_insert(weak_table_t *weak_table, weak_entry_t *new_entry) {return OSAtomicCompareAndSwapPtr(nil, new_entry, (void * volatile *)&weak_table->weak_entries);
}
5. 清理机制
5.1 对象释放时的清理
void weak_clear_no_lock(weak_table_t *weak_table, id referent) {weak_entry_t *entry = weak_entry_for_referent(weak_table, referent);if (entry == nil) return;// 将所有弱引用置为 nilweak_referrer_t *referrers = entry->referrers;size_t count = entry->num_refs;for (size_t i = 0; i < count; ++i) {objc_object **referrer = referrers[i];if (referrer) {*referrer = nil;}}// 移除 entryweak_entry_remove(weak_table, entry);
}
5.2 表格清理
void weak_compact_maybe(weak_table_t *weak_table) {size_t old_size = TABLE_SIZE(weak_table);// 当表使用率低于 1/4 时进行收缩if (weak_table->num_entries < old_size / 4) {weak_resize(weak_table, old_size / 2);}
}
6. 性能优化
6.1 哈希优化
static inline uintptr_t hash_pointer(objc_object **p) {return ((uintptr_t)p) >> 3; // 去除对齐位
}static inline size_t index_for_pointer(uintptr_t ptr, size_t mask) {return ptr & mask; // 快速取模
}
6.2 空间优化
// 使用内联数组优化小对象
if (entry->num_refs < WEAK_INLINE_COUNT) {// 使用内联存储entry->inline_referrers[entry->num_refs++] = referrer;
} else {// 转换为动态数组move_to_dynamic_storage(entry);
}
7. 注意事项
1. 线程安全:
- 所有操作都需要加锁保护
- 使用原子操作进行关键更新
- 内存管理:
- 及时清理无用的 entry
- 动态调整表大小避免内存浪费
3. 性能考虑:
- 使用内联存储优化小对象
- 哈希算法优化查找效率
- 正确性保证:
- 对象释放时正确清理所有弱引用
- 维护引用计数的准确性
这个设计在保证功能正确的同时,通过多种优化手段提供了良好的性能。
相关文章:
iOS - 弱引用表(Weak Reference Table)
1. 基本数据结构 // 弱引用表的基本结构 struct weak_table_t {weak_entry_t *weak_entries; // 保存所有的弱引用对象size_t num_entries; // 当前存储的弱引用数量uintptr_t mask; // 哈希表大小掩码uintptr_t max_hash_displacement; /…...
C#语言的网络编程
C#语言的网络编程 引言 随着互联网的飞速发展,网络编程成为了软件开发中的一个重要领域。C#语言作为一种现代编程语言,凭借其丰富的类库、良好的可读性和强大的功能,广泛应用于开发各种网络应用程序。无论是Windows应用、Web应用还是云服务…...
【操作系统】课程 4调度与死锁 同步测练 章节测验
4.1知识点导图 处理机调度与死锁相关内容的文字整理: 基本准则 资源利用率:使系统中的处理机和其他所有资源都尽可能地保持忙碌状态。系统吞吐量:单位时间内系统所完成的作业数。公平性:使各进程都获得合理的CPU时间,而…...
如何查看已经安装的python版本和相关路径信息
如何查看已经安装的python版本和相关路径信息 本文目录: 一、通过命令行模式查询 1、通过命令where python 2、通过命令print(sys.executable) 二、在 Anaconda Navigator 中 三、只安装python的环境下 一、通过命令行模式查询 同时按windowR键,输入cmd&#x…...
设计模式-结构型-适配器模式
在软件开发中,随着系统的不断扩展和模块的不断增加,往往会遇到不同模块之间接口不兼容的情况。此时,如果我们能通过某种方式将一个接口转化为另一个接口,那么开发工作将变得更加灵活和高效。适配器模式(Adapter Patter…...
鸿蒙操作系统(HarmonyOS)
鸿蒙操作系统(HarmonyOS)是华为公司推出的一款面向未来、面向全场景的分布式操作系统。它旨在为用户提供一个更加智能、便捷和安全的操作环境,支持多种终端设备之间的无缝协作。在鸿蒙应用开发中,ArkUI作为官方推荐的用户界面开发…...
基于海思soc的智能产品开发(camera sensor的两种接口)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 对于嵌入式开发设备来说,除了图像显示,图像输入也是很重要的一部分。说到图像输入,就不得不提到camera。目前ca…...
解密LLM结构化输出:代码示例与原理分析
解密LLM结构化输出:代码示例与原理分析 一、LLM结构化输出概述 1. 结构化输出的定义与优势 结构化输出指的是语言模型(LLM)生成的遵循特定格式(如JSON、XML)的数据,这些数据易于解析和处理。相较于非结构…...
Go语言的数据类型
Go语言的数据类型详解 Go语言是一门具有简洁、高效并且强类型的编程语言。它的设计理念之一是让程序员能够以清晰、简明的方式表达自己的意图。在Go语言中,数据类型是其基础构建块之一,理解不同数据类型的特点和使用场景对于编写高效的Go程序至关重要。…...
复杂园区网基本分支的构建
目录 1、各主机进行网络配置。2、交换机配置。3、配置路由交换,进行测试。4、配置路由器接口和静态路由,进行测试。5、最后测试任意两台主机通信情况 模拟环境链接 拓扑结构 说明: VLAN标签在上面的一定是GigabitEthernet接口的,…...
如何很快将文件转换成另外一种编码格式?编码?按指定编码格式编译?如何检测文件编码格式?Java .class文件编码和JVM运行期内存编码?
如何很快将文件转换成另外一种编码格式? 利用VS Code右下角的"选择编码"功能,选择"通过编码保存"可以很方便将文件转换成另外一种编码格式。尤其,在测试w/ BOM或w/o BOM, 或者ANSI编码和UTF编码转换,特别方便。VS文件另…...
《C++11》Lambda 匿名函数从入门到进阶 优缺点分析 示例
Lambda 匿名函数从入门到进阶 C11 引入了 lambda 表达式,这是一种非常强大的功能,可以让我们在代码中定义匿名函数。它们不仅使代码更加简洁,而且在处理回调、算法和多线程编程时极为方便。本文将带你从入门到进阶,全面了解 C11 …...
连接Milvus
连接到Milvus 验证Milvus服务器正在侦听哪个本地端口。将容器名称替换为您自己的名称。 docker port milvus-standalone 19530/tcp docker port milvus-standalone 2379/tcp docker port milvus-standalone 192.168.1.242:9091/api/v1/health 使用浏览器访问连接地址htt…...
Linux——修改文件夹的所属用户组和用户
一、命令 举例: 授权 MOT17 文件夹 给 hust_xxx 用户: sudo chown -R hust_xxx:hust_xxx MOT17参考 Linux授权文件夹给用户...
Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)
Vue Amazing UI 一个 Vue 3 组件库 使用 TypeScript,都是单文件组件 (SFC),支持 tree shaking 有点意思 English | 中文 Vue Amazing UI 是一个基于 Vue 3、TypeScript、Vite 等最新技术栈开发构建的现代化组件库,包含丰富的 UI 组件和常…...
计算机Steam报错failedtoloadsteamui.dll怎么解决?DLL报错要怎么修复?
计算机Steam报错“Failed to Load SteamUI.dll”?这里有专业的解决方案! 作为软件开发领域的一名从业者,我深知电脑在运行过程中可能会遇到的各种问题,尤其是像Steam这样的大型游戏平台。今天,我将为大家科普一下Stea…...
如何开发一个简单的 dApp
后端合约 执行 sui move new resource_manage 创建一个包 接着就可以开始编写合约了 首先创建两个 Struct 用来创建 Profile 并记录在 State 中 public struct State has key {id: UID,users: Table<address, address>, }public struct Profile has key {id: UID,nam…...
TDengine 签约智园数字,助力化工园区智联未来
近年来,随着化工行业对安全、环保、高效运营的要求日益提高,化工园区的数字化转型成为必然趋势。从数据孤岛到全面互联,从基础监控到智能分析,如何高效管理和利用时序数据已成为化工园区智能化升级的关键环节。作为一家专注于时序…...
《Python游戏编程入门》注-第9章8
2 游戏信息的显示 在游戏窗口的上部会显示游戏分数、游戏关卡、剩余砖块数以及剩余小球数等信息,如图12所示。 图12 游戏信息显示 使用如图13所示的代码实现以上功能。 图13 显示游戏信息的代码 其中,print_text()函数MyLibrary....
js逆向实战(1)-- 某☁️音乐下载
下载某云音乐源文件.mp4格式 首先随便点进一首歌,如图所示获取该音乐id,然后点击播放键,打开F12进行查询XHR 由此可知,实际请求网址是 https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token「你的token」url需带…...
如何快速获取Steam游戏完整文件清单:Onekey工具终极指南
如何快速获取Steam游戏完整文件清单:Onekey工具终极指南 【免费下载链接】Onekey Onekey Steam Depot Manifest Downloader 项目地址: https://gitcode.com/gh_mirrors/one/Onekey 还在为复杂的Steam游戏清单获取流程而烦恼吗?Onekey Steam Depot…...
终极免费QQ音乐QMC解码器:3分钟解锁加密音乐,实现跨平台播放自由
终极免费QQ音乐QMC解码器:3分钟解锁加密音乐,实现跨平台播放自由 【免费下载链接】qmc-decoder Fastest & best convert qmc 2 mp3 | flac tools 项目地址: https://gitcode.com/gh_mirrors/qm/qmc-decoder 还在为QQ音乐下载的加密音乐文件无…...
【图像加密】基于交替量子漫步的量子彩色图像加密解密附Matlab代码
✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…...
2025年开源大模型趋势入门必看:Qwen2.5+弹性GPU部署实战指南
2025年开源大模型趋势入门必看:Qwen2.5弹性GPU部署实战指南 1. 为什么选择Qwen2.5-7B-Instruct 如果你正在寻找一个既强大又实用的AI模型,Qwen2.5-7B-Instruct绝对值得关注。这个模型在中等体量模型中表现出色,不仅能力全面,而且…...
FanControl完全配置指南:3步打造个性化电脑散热系统
FanControl完全配置指南:3步打造个性化电脑散热系统 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/F…...
3步实现飞书文档本地转换:Cloud Document Converter全场景解决方案
3步实现飞书文档本地转换:Cloud Document Converter全场景解决方案 【免费下载链接】cloud-document-converter Convert Lark Doc to Markdown 项目地址: https://gitcode.com/gh_mirrors/cl/cloud-document-converter 想象一下,当你需要将飞书文…...
多模态大模型训练数据构建实战手册:从零到亿级高质量样本的5步标准化流水线
第一章:多模态大模型训练数据构建策略概览 2026奇点智能技术大会(https://ml-summit.org) 多模态大模型的性能上限高度依赖于训练数据的质量、多样性与对齐精度。不同于单模态模型,多模态数据需在图像、文本、音频、视频乃至传感器信号等异构模态间建立…...
亚马逊人的mbti来了?测出结果真令人哭笑不得!
做亚马逊久了,总好奇身边同行都是什么 “路子”—— 有人是数据控,算利润算到小数点后两位; 有人凭直觉选品,偏偏总能踩中蓝海; 有人社牛到站外红人随便聊,也有人只想安静守链接不被打扰。 抱着好玩、图一…...
AndroidStudio 导入老项目时Gradle与Kotlin版本冲突的排查与修复指南
1. 问题现象与原因分析 当你尝试在Android Studio中导入一个老项目时,最常遇到的拦路虎就是Gradle与Kotlin版本冲突。这个问题通常会以鲜红的错误提示出现在Build窗口中,比如: A problem occurred evaluating project :app. > Failed to a…...
拯救你的WSL2 ROS2开发:一键自动启动ros2 daemon的.bashrc配置脚本(告别topic list超时)
拯救你的WSL2 ROS2开发:一键自动启动ros2 daemon的.bashrc配置脚本(告别topic list超时) 每次打开WSL2终端都要手动输入ros2 daemon start才能正常使用ROS2工具?当你在调试机器人算法时突然发现ros2 topic list卡住不动࿰…...
