15.weak实现原理

描述

  • 系统维护了一个hash表,

    • Key是所指对象的地址,

    • Valueweak指针的地址数组

    • 弱引用,应用对象的引用计数不会+1

    • 并在对象被释放的时候自动设为nil,这是和assign本质的区别,用assign修饰对象的话会发生野指针的问题

实现过程

初始化时

  • runtime调用objc_initWeak函数创建一个新的weak指针指向修饰的对象的地址

//初始化weak表
/** 
 * Initialize a fresh weak pointer to some object location. 
 * It would be used for code like: 
 *
 * (The nil case) 
 * __weak id weakPtr;
 * (The non-nil case) 
 * NSObject *o = ...;
 * __weak id weakPtr = o;
 * 
 * @param addr Address of __weak ptr. 
 * @param val Object ptr. 
 */
id objc_initWeak(id *addr, id val)
{
    *addr = 0;
    if (!val) return nil;
    return objc_storeWeak(addr, val); // 存储weak对象
}

添加引用时

  • objc_initWeak会调用objc_storeWeak函数,更新指针指向,创建对应弱引用表

  • weak_unregister_no_lock旧对象解除注册

    *

  • weak_register_no_lock新对象添加注册

释放时

  • 调用objc_release

  • 引用计数为0调用dealloc

  • dealloc中调用了_objc_rootDealloc函数

  • _objc_rootDealloc调用了object_dispose

  • 调用objc_destructInstance

  • objc_destructInstance首先根据对象地址获取所有weak指针地址数组,遍历置为nil,然后把这weak表中所有该地址的记录删除

Last updated

Was this helpful?