- /**
- 全局的弱引用表,本质是一个hash结构,对象本身作为key,
- 存储weak修饰的指针地址的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数组采用开放定址法解决hash冲突
- uintptr_t max_hash_displacement;
- };
- NSObject * obj = [[NSObject alloc] init];
-
- __weak NSObject *p1 = obj;
- __weak NSObject *p2 = obj;
-
- NSObject ** referrer1 = &p1;
- NSObject ** referrer2 = &p2;
-
- [obj release];
hash表的key为obj,hash表的值weak_entries的referers属性被赋值为[referrer1, referrer2];
- 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 < count; ++i) {
- objc_object **referrer = referrers[i];
- if (referrer) {
- // 如果weak指针确实弱引用了对象 referent,则将weak指针设置为nil
- if (*referrer == referent) {
- *referrer = nil;
- }
- }
- }
- }
iOS在ARC下通过引入weak标识, 大大减少了以前retain或assign标识的对象在被销毁后可能出现野指针的情况,进而有效提升了代码健壮性。