属性的weak,如何实现的

2020-08-12  本文已影响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;
};

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

上一篇下一篇

猜你喜欢

热点阅读