-
Notifications
You must be signed in to change notification settings - Fork 0
iOS weak修饰的释放则自动被置为nil的实现原理
Deepin edited this page Aug 19, 2021
·
1 revision
Runtime维护着一个Weak表,用于存储指向某个对象的所有Weak指针, 这个表就是sideTable
在开源文件objc4-706中, 可以看到NSObject.mm类文件中对于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(); }
// 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 结构体重定了几个非常重要的变量。
// The order of these bits is important.
#define SIDE_TABLE_WEAKLY_REFERENCED (1UL<<0)
#define SIDE_TABLE_DEALLOCATING (1UL<<1) // MSB-ward of weak bit
#define SIDE_TABLE_RC_ONE (1UL<<2) // MSB-ward of deallocating bit
#define SIDE_TABLE_RC_PINNED (1UL<<(WORD_BITS-1))
#define SIDE_TABLE_RC_SHIFT 2
#define SIDE_TABLE_FLAG_MASK (SIDE_TABLE_RC_ONE-1)
Weak表是Hash表,Key是所指对象的地址,Value是Weak指针地址的数组
在对象被回收的时候,经过层层调用,会最终触发下面的方法将所有Weak指针的值设为nil。
runtime源码,objc-weak.m 的 arr_clear_deallocating 函数
weak指针的使用涉及到Hash表的增删改查,有一定的性能开销.