weak的特点: 同assign一样,是一种非持有关系,不同在于当属性所指对象被释放后,属性值也会自动清空。PS:assign 可以用非 OC 对象,而 weak 必须用于 OC 对象
如何实现?
当你初始化一个weak变量的时候,runtime会调用objc_initweak(id * object, id value)
id __weak obj1 = obj;
objc_initWeak(&obj1, obj);
objc_initweak-> objc_storeWeak(object, value)
首先通过value去找它对应的弱引用表
newTable = SideTable::tableForPointer(value)
weak_table_t弱引用表记录了这个对象的所有弱引用变量,weak_referrer_t数组里面存储
struct weak_table_t {
weak_entry_t *weak_entries;
size_t num_entries;
......
};
struct weak_entry_t {
DisguisedPtr<objc_object> referent;
union {
struct {
weak_referrer_t *referrers;
uintptr_t out_of_line : 1;
......
};
struct {
// out_of_line=0 is LSB of one of these (don't care which)
weak_referrer_t inline_referrers[WEAK_INLINE_COUNT];
};
};
};
当这个对象被释放的时候,会调用objec_clear_deallocating ,主要工作就是把这个对象的弱引用表找出来,找到所有的弱引用变量,清空这些变量。
参考博客: