• weak的底层原理


    在这里插入图片描述

    weak 引用在 iOS 中通过维护一个全局的弱引用表来实现。当弱引用的对象被释放时,所有指向它的弱引用会被自动置为 nil,从而防止悬挂指针。

    弱引用表(Weak Table)的键和值

    理解弱引用表的键和值对于理解 weak 引用的底层机制非常重要。下面我详细解释一下这两个概念,并用示例和图表来说明。

    键(Key)
    • 对象指针(Object Pointer):这是被 weak 引用的对象的内存地址。每个被 weak 引用的对象在弱引用表中都有一个对应的条目,其键就是这个对象的内存地址。
    值(Value)
    • 弱引用指针集合(Set of Weak Reference Pointers):这是一个集合,包含了所有指向该对象的 weak 引用指针的地址。当一个对象有多个 weak 引用时,这些引用指针的地址都会记录在集合中。

    具体示例

    示例代码
    Person *personInstance = [[Person alloc] init];
    __weak Person *weakPerson1 = personInstance;
    __weak Person *weakPerson2 = personInstance;
    

    在这个示例中:

    • personInstance 是一个 Person 对象的强引用。
    • weakPerson1weakPerson2Person 对象的两个弱引用。
    弱引用表表示
    1. 创建弱引用时
      • 假设 personInstance 的内存地址是 0x1000
      • weakPerson1 的内存地址是 0x2000
      • weakPerson2 的内存地址是 0x3000
    Weak Table:
    +-------------------+-------------------+
    | Object Pointer    | Weak Reference(s) |
    +-------------------+-------------------+
    | 0x1000            | [0x2000, 0x3000]  |  // personInstance is referenced by weakPerson1 and weakPerson2
    +-------------------+-------------------+
    

    在这个弱引用表中:

    • 0x1000personInstance 的内存地址。
    • [0x2000, 0x3000] 是一个集合,包含了所有指向 personInstance 的弱引用指针(weakPerson1weakPerson2 的地址)。

    对象释放时

    personInstance 的引用计数变为零,系统准备释放该对象时,运行时会执行以下操作:

    1. 找到所有弱引用

      • 在弱引用表中查找键 0x1000,找到对应的值 [0x2000, 0x3000]
    2. nil

      • 0x20000x3000 地址上的值置为 nil
    3. 删除条目

      • 从弱引用表中删除键 0x1000 的条目。
    Weak Table (before release):
    +-------------------+-------------------+
    | Object Pointer    | Weak Reference(s) |
    +-------------------+-------------------+
    | 0x1000            | [0x2000, 0x3000]  |
    +-------------------+-------------------+
    
    Weak Table (after release):
    +-------------------+-------------------+
    | Object Pointer    | Weak Reference(s) |
    +-------------------+-------------------+
    | (nil)             | [nil, nil]        |  // personInstance 已被释放,weakPerson1 和 weakPerson2 被置为 nil
    +-------------------+-------------------+
    

    关键函数

    在实现弱引用机制时,运行时系统使用以下关键函数:

    libobjc 中的一系列 API

    1. objc_initWeak:初始化一个弱引用,将其添加到弱引用表中。
    2. objc_loadWeak:读取一个弱引用的值,确保在对象被释放后返回 nil
    3. objc_storeWeak:给弱引用赋值,并更新弱引用表。
    4. objc_destroyWeak:销毁一个弱引用,并从弱引用表中移除对应的条目。

    概述

    弱引用表的键是被引用对象的内存地址,而值是一个集合,包含了所有指向该对象的弱引用指针的地址。当对象被释放时,运行时会在弱引用表中找到所有指向该对象的弱引用,并将它们置为 nil,然后删除对应的条目。通过这种机制,iOS 保证了 weak 引用的安全性和可靠性。

  • 相关阅读:
    【从头构筑C#知识体系】1.7 运算符和表达式
    计算机毕业设计(附源码)python在线辅导答疑系统
    【ATT&CK】MITRE Caldera-emu插件
    B2C在线教育商城--前后端分离部署
    NodeJs 实践之他说
    弹性布局flex或者grid元素平分,实际会被内容撑大,问题剖析
    Windows安装RabbitMQ详细教程
    行业追踪,2023-09-12
    《HelloGitHub》第 80 期
    SpringBoot(二):基础配置文件、yaml语法、多环境开发配置
  • 原文地址:https://blog.csdn.net/qfeung/article/details/139457825