美文网首页
ARC实现源码笔记

ARC实现源码笔记

作者: 解放者莫雷尔 | 来源:发表于2016-12-20 13:37 被阅读0次

下面是runtime中关于ARC的数据结构部分:

未命名.001.jpeg

Weak引用实现

NSObject中定义了两个方法:

id objc_storeWeak(id *location, id newObj)
{
    return storeWeak<true/*old*/, true/*new*/, true/*crash*/>
        (location, (objc_object *)newObj);
}

id objc_storeWeakOrNil(id *location, id newObj)
{
    return storeWeak<true/*old*/, true/*new*/, false/*crash*/>
        (location, (objc_object *)newObj);
}

第二个方法与第一个作用类似,都是调用的storeWeak模版函数,只不过第三个模版参数传入的值是false,表示如果要存储的值释放了或者要存储的值的类不支持weak引用,就会存储一个nil,而不是crash掉。

Runtime会维护一个SideTables,如下代码所示:

alignas(StripedMap<SideTable>) static uint8_t 
    SideTableBuf[sizeof(StripedMap<SideTable>)];

static void SideTableInit() {
    new (SideTableBuf) StripedMap<SideTable>();
}
//SideTables就是一个StripedMap,id为key,值为SideTable
static StripedMap<SideTable>& SideTables() {
    return *reinterpret_cast<StripedMap<SideTable>*>(SideTableBuf);
}

而SideTables就是一个StripedMap,它以id为key,sideTable为值。那么SideTable的结构式什么样子呢?如下:

struct SideTable {
    spinlock_t slock;
    RefcountMap refcnts;
    weak_table_t weak_table;

    SideTable() {
        memset(&weak_table, 0, sizeof(weak_table));
    }

    ~SideTable() {
        _objc_fatal("Do not delete SideTable.");
    }

    void lock() { slock.lock(); }
    void unlock() { slock.unlock(); }
    bool trylock() { return slock.trylock(); }

    // Address-ordered lock discipline for a pair of side tables.

    template<bool HaveOld, bool HaveNew>
    static void lockTwo(SideTable *lock1, SideTable *lock2);
    template<bool HaveOld, bool HaveNew>
    static void unlockTwo(SideTable *lock1, SideTable *lock2);
};

我们关注的是weak_table_t这个数据结构,它针对这个对象的weak引用表。如下:

struct weak_table_t {
    weak_entry_t *weak_entries;//引用项
    size_t    num_entries;//引用次数
    uintptr_t mask;
    uintptr_t max_hash_displacement;
};

待续。。。

相关文章

网友评论

      本文标题:ARC实现源码笔记

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