我正在从https://github.com/opensource-apple/objc4读取objc的代码。

在代码中,有一个SideTable结构,其中包含相应对象的引用计数和weak_table_t。

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);
};

而且,由于每个对象的SideTable存储在StripedMap中,该对象的SideTable可以由SideTables()[obj]检索,而StripedMap实际上是使用对象地址的哈希值作为索引的数组。

但是根据weak_entry_for_referent的代码,运行时通过检查weak_table-> weak_entries [index] .referent来获取引用对象的weak_entry_t。
static weak_entry_t *
weak_entry_for_referent(weak_table_t *weak_table, objc_object *referent)
{
    assert(referent);

    weak_entry_t *weak_entries = weak_table->weak_entries;

    if (!weak_entries) return nil;

    size_t index = hash_pointer(referent) & weak_table->mask;
    size_t hash_displacement = 0;
    while (weak_table->weak_entries[index].referent != referent) {
        index = (index+1) & weak_table->mask;
        hash_displacement++;
        if (hash_displacement > weak_table->max_hash_displacement) {
            return nil;
        }
    }

    return &weak_table->weak_entries[index];
}

这意味着weak_table包含的对象多于单个对象的weak条目。那么,为什么weak_table_t是SideTable的成员而不是全局数据的成员?

由于找不到真正初始化对象的SideTable的代码(storeStrong仅使用SideTable而不先对其进行初始化)和weak_table,因此我不太了解事情在后台如何工作。

有人可以给我提示吗?

最佳答案

我能弄清的唯一合理原因是:

所有SideTable实例的SideTableBuf实际上是一个存储桶数组。可以将不同的对象放在同一存储桶中。因此,根据哈希算法,单个SideTable可以用于不同的指针。然后,weak_table实际上包含用于不同引用对象的weak_entry_t。这就是为什么我们需要通过以下方式检查参考对象:

while (weak_table->weak_entries[index].referent != referent)

而且weak_table仅用于当前的SideTable,因此它不能是全局数据。

关于ios - 为什么薄弱表_t在Objective-C运行时中成为SideTable的成员?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35427340/

10-12 01:52