1.weak的基本用法
weak是弱引用,用weak来修饰、描述所引用的对象计数器并不会增加,而且weak会在引用对象被释放时自动置为nil,这也就避免了野指针访问坏内存而引起奔溃的情况,另外weak也可以解决循环引用。
2.weak实现原理的概括
Runtime维护了一个weak表,用于存储指向某个对象的所有weak指针。weak表其实是一个hash(哈希)表,Key是所指对象的地址,Value是weak指针的地址(这个地址的值是所指对象指针的地址,就是地址的地址)集合(当weak指针的数量小于等于4时,是数组, 超过时,会变成hash表)。
weak的实现原理可以概括一下三步:
- 初始化时:runtime会调用objc_initWeak函数,初始化一个新的weak指针指向对象的地址。
- 添加引用时:objc_initWeak函数会调用objc_storeWeak()函数,objc_storeWeak()的作用是更新指针指向,创建对应的弱引用表。
- 释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。
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;
};
网友评论