美文网首页
属性的weak,如何实现的

属性的weak,如何实现的

作者: 一个半吊子工程师 | 来源:发表于2020-08-12 11:31 被阅读0次

    runtime对注册的类会进行布局,
    1.对于weak修饰的对象会放入一个hash表中;
    2.用weak指向的对象内存地址作为key;
    3.当此对象的引用计数为0的时候会dealloc
    假如weak指向的对象内存地址是a,那么就会以a为在这个weak表中搜索,找到所有以a为weak对象,从而设置为nil

    weak释放为nil过程
    weak被释放为nil,需要对对象整个释放过程了解,如下是对象释放的整体流程:
    1、调用objc_release
    2、因为对象的引用计数为0,所以执行dealloc
    3、在dealloc中,调用了_objc_rootDealloc函数
    4、在_objc_rootDealloc中,调用了object_dispose函数
    5、调用objc_destructInstance
    6、最后调用objc_clear_deallocating

    对象准备释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entryweak表中删除,最后清理对象的记录。

    总结

    weakRuntime维护了一个hash(哈希)表,用于存储指向某个对象的所有weak指针。weak表其实是一个hash(哈希)表Key所指对象的地址,Value是weak指针的地址(这个地址的值是所指对象指针的地址数组

    1、初始化时:runtime 会调用objc_initWeak函数,初始化一个新的 weak指针 指向对象的地址。

    2、添加引用时:objc_initWeak函数 会调用 objc_storeWeak() 函数, objc_storeWeak()的作用是更新指针指向,创建对应的弱引用表。

    3、释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有 weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个 entryweak表中删除,最后清理对象的记录。

    sideTable

    struct SideTable {
        // 保证原子操作的自旋锁
        spinlock_t slock;
        // 引用计数的 hash 表
        RefcountMap refcnts;
        // weak 引用全局 hash 表
        weak_table_t weak_table;
    }
    
    struct weak_table_t {
        // 保存了所有指向指定对象的 weak 指针
        weak_entry_t *weak_entries;
        // 存储空间
        size_t    num_entries;
        // 参与判断引用计数辅助量
        uintptr_t mask;
        // hash key 最大偏移值
        uintptr_t max_hash_displacement;
    };
    

    站在巨人的肩膀上学习!如有侵权,请联系删除

    相关文章

      网友评论

          本文标题:属性的weak,如何实现的

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