行业知识
weak 的实现原理
2026-10-21 22:43:43
来源:互联网转载
�index.php/tags-41973.html" >� iOS 在运行时维护着一个全局的弱引用表,该表是一个 hash 表,hash表的 key 是 weak 对象的地址,value 是指向该对象的所有 weak 指针的地址数组。
/** 全局的弱引用表,本质是一个hash结构,object作为key, weak_entry_t作为value */struct weak_table_t { // 保存了所有指向特地对象的 weak指针集合 weak_entry_t *weak_entries; // hash数组中元素个数 size_t num_entries; // hash数组的长度,而不是元素个数。比如,数组长度可能是64,而元素个数仅存了2个 uintptr_t mask; // hash冲突最大次数, 采用开放定址法解决hash冲突 uintptr_t max_hash_displacement;}; 以下述代码为例: NSObject * obj = [[NSObject alloc] init];__weak NSObject *p1 = obj;__weak NSObject *p2 = obj;objc_object ** referrer1 = &p1;objc_object ** referrer2 = &p2;[obj release];
hash表的key为obj,hash表的值weak_entries的referers属性被赋值为[referrer1, referrer2];
() 当weak修饰的对象obj被销毁时,iOS在运行时会从哈希表中查找到所有指向此对象的 weak 指针,并将其全部置为空 nil,即通过执行*referrer1 = NULL和*referrer2 = NULL,实现将p1和p2置为NULL。weak_clear_no_lock(weak_table_t *weak_table, id referent_id) { // 在weak_table中对应的weak_entry_t objc_object *referent = (objc_object *)referent_id; weak_entry_t *entry = weak_entry_for_referent(weak_table, referent); weak_referrer_t referrers = entry->referrers; int count = TABLE_SIZE(entry); for (size_t i = 0; i iOS在ARC下通过引入weak标识, 大大减少了以前retain或assign标识的对象在被销毁后可能出现野指针的情况,进而有效提升了代码健壮性。
()
上一篇:服务器怎么给玩家礼包兑换?
下一篇:服务器都是灰怎么清理?