Я читаю код objc от https://github.com/opensource-apple/objc4.Почему weak_table_t является членом SideTable во время выполнения Objective-C?
В коде есть структура 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 объекта может быть получен с помощью SideTables() [OBJ] как SideTable каждого объекта хранится в StripedMap, которая на самом деле массив с использованием хэш-значение адреса объекта в качестве индекса ,
Но в соответствии с кодом weak_entry_for_referent среда выполнения получает weak_entry_t референта, проверяя weak_table-> weak_entries [index] .referent.
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_table_t является членом SideTable вместо глобальных данных?
Поскольку я не могу найти код, который действительно инициализирует SideTable объекта (storeStrong просто использует SideTable, не инициализируя его сначала) и weak_table, я не могу понять, как все работает в фоновом режиме.
Может ли кто-нибудь дать мне подсказку?
Я не понимаю вашего заключения. Слабая таблица содержит список всех других объектов, ссылающихся на один конкретный объект в учетной записи. Функция возвращает запись для конкретного объекта в учетной записи и реферер (референт). Поэтому каждый объект имеет (локальную) таблицу для своих источников. –
По моему мнению, weak_entry_for_referent вернет запись в weak_table-> weak_entries для референта (объект ссылается на слабые ссылки). Если weak_table или weak_table-> weak_entries в SideTable содержит только слабые источники для себя, почему мы должны проверять, является ли референт референтом, которого мы ищем, while (weak_table-> weak_entries [index] .referent! = Referent) " ? –
Потому что он принимает ссылку на объект ('objc_object') и возвращает всю запись (' weak_entry_t'). Таким образом, вы можете получить запись для справки. 'weak_entry_t' содержит больше информации, чем' id' (aka 'objc_object'). –