返回
揭秘底层 weak 的实现原理——深入剖析 objc_initWeak
IOS
2024-01-09 18:28:06
引言
在 Objective-C 中,weak 修饰符用于表示对对象的弱引用,这是一种不影响对象生命周期的引用方式。与强引用不同,weak 引用不会阻止对象被释放,从而避免了循环引用的可能性。
objc_initWeak
objc_initWeak 是 weak 机制的核心函数。它负责初始化一个 SideTable 结构,用于管理弱引用。SideTable 是一个哈希表,其中键是对象的地址,值是一个指向该对象弱引用的指针。
当我们创建一个 weak 引用时,objc_initWeak 会执行以下步骤:
- 创建一个 SideTable,如果还没有的话。
- 在 SideTable 中查找对象的地址。
- 如果对象不存在,则将一个 weak 指针添加到 SideTable 中,并将其设置为 nil。
- 返回 weak 指针。
storeWeak
storeWeak 函数用于将对象存储到 weak 引用中。它执行以下步骤:
- 调用 objc_initWeak 获取弱指针。
- 将对象分配给 weak 指针。
SideTable
SideTable 是一个哈希表,用于管理弱引用。它包含以下字段:
table
: 一个哈希表,其中键是对象的地址,值是 weak 指针。count
: 哈希表中的条目数。freeList
: 一个 free list,用于存储已释放 weak 指针的地址。lock
: 一个互斥锁,用于同步对 SideTable 的访问。
实现细节
weak 实现的更详细细节涉及以下内容:
- 哈希冲突处理: 当两个对象映射到同一哈希桶时,SideTable 使用链表来解决冲突。
- 弱指针的生命周期: weak 指针的生存期与 SideTable 的生存期相同。当 SideTable 被释放时,所有 weak 指针也将被释放。
- 内存管理: SideTable 和 weak 指针都在运行时进行管理,不需要显式释放。
使用 weak 的注意事项
使用 weak 时,需要考虑以下注意事项:
- 避免循环引用: weak 引用可以防止循环引用,但不能防止对象图中其他类型的引用循环。
- 对象生命周期: 弱引用不影响对象的释放,因此在使用 weak 引用时,必须意识到对象的生命周期。
- 并发安全性: SideTable 是线程安全的,但访问 weak 引用本身不是线程安全的。
结论
weak 是 Objective-C 中一种强大的工具,用于管理引用和防止循环引用。通过理解其底层实现原理,我们可以更好地利用 weak,优化代码并提高内存效率。