美文网首页
Weak相关

Weak相关

作者: 埃辛诺斯忍 | 来源:发表于2021-01-06 10:50 被阅读0次

    整理一下自己学到的知识,方便以后查看

    1.什么情况使用 weak 关键字,相比 assign 有什么不同?

    1.在ARC中,在有可能出现循环引用的时候,往往要通过让其中一端使用weak来解决,比如:delegate代理属性
    2.自身已经对它进行一次强引用,没有必要再强引用一次,此时也会使用weak,自定义IBOutlet控件属性一般也使用weak;当然,也可以使用strong。(IBOutlet本身有一个强引用)

    不同点:

    1)weak 此特质表明该属性定义了一种“非拥有关系” (nonowning relationship)。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assign类似, 然而在属性所指的对象遭到摧毁时,属性值也会清空(nil)。 而 assign 的“设置方法”只会执行针对“纯量类型” (scalar type,例如 CGFloat 或 NSlnteger 等)的简单赋值操作。
    2)assigin 可以用非OC对象,而weak必须用于OC对象

    weak修饰的属性可以在ARC自动置为nil的原理

    系统有一个SideTables的哈希表,用来管理所有对象的引用计数以及weak指针。

    struct SideTable {
        spinlock_t slock;
        RefcountMap refcnts; // 引用计数 
        weak_table_t weak_table; // 弱引用表 ,weak_table_t是保存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.inline_referrers是用来存放weak指针的数组,最大可以装4个,如果超过了,就用referrers继续储存;
    2.referent是用来储存对象的的地址的。

    对象销毁时发生的事:
    1.dealoc
    2._objc_rootDealloc(self);
    3.obj->rootDealloc();
    4.object_dispose(this);
    5.objc_destructInstance(obj);
    6.clearDeallocating函数里面会调用clearDeallocating_slow();
    7.clearDeallocating_slow();里面会调用weak_clear_no_lock(&table.weak_table, (id)this); 。
    8.weak_clear_no_lock函数中将referrers数组或者inline_referrers数组遍历,赋值为nil。

    相关文章

      网友评论

          本文标题:Weak相关

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