美文网首页
weak指针是如何实现自动设置为nil的

weak指针是如何实现自动设置为nil的

作者: Sweet丶 | 来源:发表于2020-03-27 14:35 被阅读0次

    在ARC中,weak指针修饰的变量会在指向的对象销毁时自动置为nil,系统是怎么做到的呢?这里从本质和源码出发来解释。源码

    iOS系统中维护着一个SideTables的哈希表,这个哈希表用来管理所有对象的引用计数和weak指针。

    一、找到weak指针存储的位置

    SideTables哈希表里面装着的元素的key为对象,value为SideTable的结构体!

    struct SideTable {
        spinlock_t slock;
        RefcountMap refcnts; // 引用计数 
        weak_table_t weak_table; // 弱引用表 
    }
    

    由上面可知weak_table_t是系统保存weak指针的结构。

    存储weak指针的结构体weak_table_t

    struct weak_table_t {
        weak_entry_t *weak_entries;
        size_t    num_entries;
    };
    
    typedef DisguisedPtr<objc_object *> weak_referrer_t;
    #define WEAK_INLINE_COUNT 4
    struct weak_entry_t {// 本来是一个C++结构体, 简化后如下
        DisguisedPtr<objc_object> referent;
        weak_referrer_t *referrers;
        weak_referrer_t  inline_referrers[WEAK_INLINE_COUNT]; 
    };
    

    由上可知:

    1. referent是存储被引用对象的地址.
    2. inline_referrers是用来装weak指针的数组,不过数量只有WEAK_INLINE_COUNT=4个.
    3. referrers也是存储weak指针的数组,但是当inline_referrers不够的时候才会使用的.
    二、系统在对象销毁时的做法

    在对象销毁时会做的事情,根据源码追踪重要的步骤:

    1. 调用dealloc
    2. _objc_rootDealloc(self);
    3. obj->rootDealloc();
    4. object_dispose(this);
    5. 先调用objc_destructInstance(obj);清楚对象相关联的东西, 之后再调用free(obj);释放对象。
    6. objc_destructInstance(obj);会做的事情
    // This order is important.
     if (cxx) object_cxxDestruct(obj); 
     if (assoc) _object_remove_assocations(obj);// 清除属性关联
     obj->clearDeallocating();
    
    1. clearDeallocating函数里面会调用clearDeallocating_slow();
    2. clearDeallocating_slow();里面会调用weak_clear_no_lock(&table.weak_table, (id)this);
    3. weak_clear_no_lock函数中将referrers数组或者inline_referrers数组遍历,赋值为nil。

    相关文章

      网友评论

          本文标题:weak指针是如何实现自动设置为nil的

          本文链接:https://www.haomeiwen.com/subject/yzncuhtx.html