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 ,主要工作就是把這個對象的弱引用表找出來,找到所有的弱引用變量,清空這些變量。
參考博客: