MST

星途 面试题库

面试题:Objective-C中weak属性的实现原理

深入解释Objective-C中weak属性是如何实现的?当对象的最后一个强引用被释放后,weak引用指向的对象发生了什么变化?系统是如何处理这些weak引用的?
21.4万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

weak属性的实现原理

  1. SideTable数据结构:在Objective-C的runtime中,维护了一个SideTable的结构。每个SideTable对象包含了一个weak_table_t,这个weak_table_t用于存储对象的弱引用信息。SideTable是通过散列表(哈希表)的形式,根据对象的地址来索引,这样可以快速定位到某个对象对应的SideTable
  2. weak_entry_t数组weak_table_t内部包含一个weak_entry_t类型的动态数组。每个weak_entry_t结构体记录了一个被弱引用的对象以及指向该对象的所有弱引用指针的集合。weak_entry_t中使用referent指向被弱引用的对象,使用referrers数组来存储指向该对象的弱引用指针。当弱引用的对象数量增加时,referrers数组会动态扩容。

对象最后一个强引用释放后,weak引用指向对象的变化

当对象的最后一个强引用被释放后,该对象会被释放,内存被回收。而指向该对象的所有weak引用会自动被设置为nil。这是weak属性非常重要的特性,它可以避免野指针(dangling pointer)的产生,确保程序在对象释放后,所有对该对象的弱引用都是安全的。

系统对weak引用的处理

  1. 对象释放时:当对象的引用计数变为0,即将被释放时,runtime会根据对象的地址找到对应的SideTable,然后在SideTableweak_table_t中找到对应的weak_entry_t。接着遍历weak_entry_t中的referrers数组,将其中存储的所有弱引用指针都设置为nil
  2. 弱引用赋值时:当创建一个新的weak引用,即将一个对象赋值给一个weak变量时,runtime同样会根据对象的地址找到对应的SideTable,如果该对象对应的weak_entry_t不存在,则会创建一个新的weak_entry_t并添加到weak_table_t的动态数组中。然后将新的弱引用指针添加到weak_entry_treferrers数组里。