MOFASHY

Live Is Life

iOS Weak实现原理解析

iOS的weak实现原理基于Objective-C运行时和SideTable机制,核心是通过‌弱引用表‌(weak_table_t)和‌引用计数表‌(SideTable)协同管理对象生命周期。以下是关键细节:


一、底层数据结构

  • SideTable‌:每个对象关联一个SideTable,包含:

    • spinlock_t(自旋锁):保证线程安全。
    • RefcountMap(引用计数表):存储对象的引用计数。
    • weak_table_t(弱引用表):存储所有指向该对象的weak指针。
  • weak_table_t:全局哈希表,以对象地址为key,存储所有指向该对象的弱引用指针地址数组(value)。

    1
    2
    3
    4
    5
    6
    struct weak_table_t {
    weak_entry_t *weak_entries; // 动态数组,存储弱引用条目
    size_t num_entries; // 当前条目数
    uintptr_t mask; // 哈希表容量掩码
    uintptr_t max_hash_displacement; // 最大哈希冲突步长
    };
  • weak_entry_t:哈希表的条目,记录对象地址(referent)和弱引用指针集合(referrers),采用共用体优化内存占用。


二、weak指针的工作流程

  1. 初始化

    • 当声明__weak id obj = strongObj时,编译器调用objc_initWeak函数,。
    • 运行时将weak指针地址(&obj)和对象地址(strongObj)注册到弱引用表中。
  2. ‌存储方式

    • 弱引用表使用对象的地址作为键,通过哈希表快速定位到对应的weak_entry_t
    • weak_entry_t内部存储所有指向该对象的weak指针地址(数组或链表结构)。
    • 通过自旋锁保证多线程环境下弱引用表的操作安全性。
  3. 对象释放时

    • 当对象的引用计数为0时,dealloc方法会调用weak_clear_no_lock
    • 遍历弱引用表中所有指向该对象的weak指针,将其置为nil(防止悬垂指针)。
    • 清理完成后,从weak表中删除对应的weak_entry_t条目。

三、自动置nil机制

  • 触发时机‌:对象被释放时,通过objc_destructInstance触发弱引用清理。
  • 线程安全‌:通过SideTable的自旋锁保证多线程下弱引用表的操作安全。
  • 性能优化‌:弱引用表使用开放寻址法解决哈希冲突,减少内存碎片。

四、与unsafe_unretained的区别


特性 weak unsafe_unretained
自动置nil
安全性 高(避免野指针) 低(可能访问已释放对象)
性能开销 有(维护weak表)
使用场景 循环引用解决 性能敏感且能确保对象生命周期的场景
兼容性 仅ARC环境 ARC/MRC均可

五、性能优化建议

  1. 避免过度使用weak‌:每个weak引用都需要维护全局weak表,频繁操作会影响性能。
  2. 优先使用strong‌:在明确知道不会造成循环引用的场景使用strong引用。
  3. 局部weak变量‌:方法内部的weak变量在作用域结束后会自动清理,比属性更高效。
  4. 注意线程安全‌:weak操作不是完全线程安全的,多线程环境需谨慎。

六、典型应用场景

  1. Delegate模式‌:防止相互强引用导致的内存泄漏。
  2. Block捕获‌:通过__weak typeof(self)配合__strong临时强引用,避免block执行期间对象意外释放。
  3. NSTimer目标对象‌:解决timer与目标对象间的循环引用。
  4. 父子对象关系‌:子对象对父对象的引用通常应为weak。

weak的实现本质是‌通过全局弱引用表动态跟踪对象状态‌,结合SideTable的线程安全机制和哈希表高效查找,实现了安全、自动化的弱引用管理。这一设计平衡了内存安全与运行时性能。

引用链接:
[1] iOS之深入解析weak关键字的底层原理 - CSDN下载
[2] 「iOS」————weak底层原理 - CSDN博客
[3] iOS——weak实现原理 - CSDN博客
[4] iOS weak的实现原理 - www.cloud.tencent.com
[5] [iOS] weak关键字的实现原理 - CSDN博客
[6] 深入解析Objective-C中的weak引用实现原理,-CSDN博客 - CSDN博客
[7] [OC学习笔记]weak的实现原理 - CSDN博客
[8] 理解Objective-C 弱引用与内存管理 - CSDN博客
[9] iOS开发进阶(十六): Objective-C block、weakself、strongself_data - CSDN博客
[10] 浅析objective-c中的strong和weak - CSDN博客
[11] weak的底层原理 - CSDN博客
[12] 揭开iOS 中 weak 指针的神秘面纱:从原理到实践 - 掘金开发者社区
[13] [iOS开发] ——weak底层原理 - CSDN博客
[14] 老生常谈的iOS- weak原理,你真的懂得还是为了应付面试 - 博客园
[15] [iOS]-weak底层原理(sidetable相关,附带引用计数原理) - CSDN博客
[16] [iOS] —— 属性关键字及weak关键字底层原理_ios weak-CSDN博客 - CSDN博客
[17] iOS_Runtime是什么?原理?作用?怎么实现weak?使用 - 腾讯云
[18] iOS中Objective-C&Swift知识点梳理 - Jonathan
[19] Tip4 - 关于 Weak 应该知道的 - 掘金开发者社区
[20] iOS weak的实现原理详解 - 简书 - 简书社区
[21] iOS weak实现原理和销毁过程 - 简书社区
[22] iOS内存管理08 – weak的底层实现原理 - 简书 - 简书社区
[23] iOS weak 底层实现原理 - luowei.github.io
[24] iOS weak 底层实现原理(二):objc-weak 函数列表全解析_牛客网 - 牛客网
[25] [iOS分类、关联对象]如何使用关联对象给分类实现一个weak的属性 - CSDN博客
[26] iOS弱引用 - CSDN博客