weak的底层原理

打印 上一主题 下一主题

主题 631|帖子 631|积分 1893


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

   明白弱引用表的键和值对于明白 weak 引用的底层机制非常紧张。下面我具体表明一下这两个概念,并用示例和图表来阐明。
  键(Key)



  • 对象指针(Object Pointer):这是被 weak 引用的对象的内存地址。每个被 weak 引用的对象在弱引用表中都有一个对应的条目,其键就是这个对象的内存地址。
值(Value)



  • 弱引用指针集合(Set of Weak Reference Pointers):这是一个集合,包罗了所有指向该对象的 weak 引用指针的地址。当一个对象有多个 weak 引用时,这些引用指针的地址都会记载在集合中。
具体示例

示例代码

  1. Person *personInstance = [[Person alloc] init];
  2. __weak Person *weakPerson1 = personInstance;
  3. __weak Person *weakPerson2 = personInstance;
复制代码
在这个示例中:


  • personInstance 是一个 Person 对象的强引用。
  • weakPerson1 和 weakPerson2 是 Person 对象的两个弱引用。
弱引用表表现


  • 创建弱引用时

    • 假设 personInstance 的内存地址是 0x1000。
    • weakPerson1 的内存地址是 0x2000。
    • weakPerson2 的内存地址是 0x3000。

  1. Weak Table:
  2. +-------------------+-------------------+
  3. | Object Pointer    | Weak Reference(s) |
  4. +-------------------+-------------------+
  5. | 0x1000            | [0x2000, 0x3000]  |  // personInstance is referenced by weakPerson1 and weakPerson2
  6. +-------------------+-------------------+
复制代码
在这个弱引用表中:


  • 键 0x1000 是 personInstance 的内存地址。
  • 值 [0x2000, 0x3000] 是一个集合,包罗了所有指向 personInstance 的弱引用指针(weakPerson1 和 weakPerson2 的地址)。
对象开释时

当 personInstance 的引用计数变为零,体系预备开释该对象时,运行时会执行以下操纵:

  • 找到所有弱引用

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

  • 置 nil

    • 将 0x2000 和 0x3000 地址上的值置为 nil。

  • 删除条目

    • 从弱引用表中删除键 0x1000 的条目。

  1. Weak Table (before release):
  2. +-------------------+-------------------+
  3. | Object Pointer    | Weak Reference(s) |
  4. +-------------------+-------------------+
  5. | 0x1000            | [0x2000, 0x3000]  |
  6. +-------------------+-------------------+
  7. Weak Table (after release):
  8. +-------------------+-------------------+
  9. | Object Pointer    | Weak Reference(s) |
  10. +-------------------+-------------------+
  11. | (nil)             | [nil, nil]        |  // personInstance 已被释放,weakPerson1 和 weakPerson2 被置为 nil
  12. +-------------------+-------------------+
复制代码
关键函数

在实现弱引用机制时,运行时体系利用以下关键函数:
   libobjc 中的一系列 API
  

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

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

花瓣小跑

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表