整理一下自己學(xué)到的知識克蚂,方便以后查看
1.什么情況使用 weak 關(guān)鍵字鸭巴,相比 assign 有什么不同吗货?
1.在ARC中,在有可能出現(xiàn)循環(huán)引用的時候,往往要通過讓其中一端使用weak來解決,比如:delegate代理屬性
2.自身已經(jīng)對它進(jìn)行一次強引用,沒有必要再強引用一次,此時也會使用weak,自定義IBOutlet控件屬性一般也使用weak字逗;當(dāng)然急前,也可以使用strong醒陆。(IBOutlet本身有一個強引用)
不同點:
1)weak 此特質(zhì)表明該屬性定義了一種“非擁有關(guān)系” (nonowning relationship)。為這種屬性設(shè)置新值時裆针,設(shè)置方法既不保留新值刨摩,也不釋放舊值。此特質(zhì)同assign類似世吨, 然而在屬性所指的對象遭到摧毀時澡刹,屬性值也會清空(nil)。 而 assign 的“設(shè)置方法”只會執(zhí)行針對“純量類型” (scalar type耘婚,例如 CGFloat 或 NSlnteger 等)的簡單賦值操作罢浇。
2)assigin 可以用非OC對象,而weak必須用于OC對象
weak修飾的屬性可以在ARC自動置為nil的原理
系統(tǒng)有一個SideTables的哈希表,用來管理所有對象的引用計數(shù)以及weak指針沐祷。
struct SideTable {
spinlock_t slock;
RefcountMap refcnts; // 引用計數(shù)
weak_table_t weak_table; // 弱引用表 嚷闭,weak_table_t是保存weak指針的
}
weak_table_t的結(jié)構(gòu)體
struct weak_table_t {
weak_entry_t *weak_entries;
size_t num_entries;
};
typedef DisguisedPtr<objc_object *> weak_referrer_t;
#define WEAK_INLINE_COUNT 4
struct weak_entry_t {// 本來是一個C++結(jié)構(gòu)體, 簡化后如下
DisguisedPtr<objc_object> referent;
weak_referrer_t *referrers;
weak_referrer_t inline_referrers[WEAK_INLINE_COUNT];
};
1.inline_referrers是用來存放weak指針的數(shù)組,最大可以裝4個赖临,如果超過了胞锰,就用referrers繼續(xù)儲存;
2.referent是用來儲存對象的的地址的兢榨。
對象銷毀時發(fā)生的事:
1.dealoc
2._objc_rootDealloc(self);
3.obj->rootDealloc();
4.object_dispose(this);
5.objc_destructInstance(obj);
6.clearDeallocating函數(shù)里面會調(diào)用clearDeallocating_slow();
7.clearDeallocating_slow();里面會調(diào)用weak_clear_no_lock(&table.weak_table, (id)this); 嗅榕。
8.weak_clear_no_lock函數(shù)中將referrers數(shù)組或者inline_referrers數(shù)組遍歷,賦值為nil色乾。