66:weak底層實(shí)現(xiàn)的流程
1: Runtime全局維護(hù)了一個(gè)全局映射表StripedMap较店,根據(jù)對(duì)象的地址能夠獲取對(duì)應(yīng)的散列表SideTable(注意J堪恕!梁呈!也有可能是多個(gè)對(duì)象共用一個(gè)散列表)婚度,散列表SideTable之中包含有weak表weak_table_t,weak_table_t中根據(jù)對(duì)象的地址能夠查到該對(duì)象對(duì)應(yīng)的weak_entry_t實(shí)體,weak_entry_t用來(lái)管理對(duì)象的所有的weak指針蝗茁,weak指針存儲(chǔ)在weak_referrer_t中醋虏。
2: 當(dāng)我們?cè)谟胈_weak修飾對(duì)象的時(shí)候,運(yùn)行時(shí)Runtime會(huì)在底層調(diào)用objc_initWeak()方法
3: objc_initWeak()方法會(huì)調(diào)用storeWeak()哮翘;
4: storeWeak()這個(gè)函數(shù)會(huì)先判斷對(duì)象是否初始化颈嚼,如果未初始化,則進(jìn)行對(duì)象初始化饭寺,然后創(chuàng)建對(duì)應(yīng)的SideTable阻课;如果對(duì)象已經(jīng)有SideTable,那么判斷weak指針是否需要更新艰匙,更新操作就是刪除對(duì)應(yīng)location位置的weak_entry_t對(duì)象限煞,創(chuàng)建新的weak_entry_t,然后插入到weak表weak_table_t中员凝。
66.1: weak指針移除原理
1署驻、移除時(shí)機(jī):調(diào)用對(duì)象的dealloc方法時(shí),中間會(huì)調(diào)用clearDeallocating健霹,其中會(huì)調(diào)用weak_clear_no_lock對(duì)weak指針進(jìn)行移除旺上。
2、移除原理:weak_clear_no_lock底層會(huì)獲取weak表weak_table_t中的實(shí)體weak_entry_t糖埋,然后拿到其中的weak_referrer_t抚官,拿到weak_referrer_t之后,遍歷并將其中的所有weak指針置為nil阶捆,最后把這個(gè)weak_entry_t從weak_table_t中移除。
3钦听、weak指針本質(zhì):從源碼中可以看出weak指針的類(lèi)型為是objc_object**洒试,是對(duì)象的二維指針,就是指向?qū)ο蟮刂返闹羔槨?/p>
67:nil朴上、Nil垒棋、NULL、NSNull的區(qū)別
nil:指向一個(gè)對(duì)象的空指針
Nil:指向一個(gè)類(lèi)的空指針
NULL:指向其他類(lèi)型(如:基本類(lèi)型痪宰、C類(lèi)型)的空指針
NSNull:通常表示集合中的空值
舉例
NSURL *url = nil;
Class class? = Nil;
int *pointerInt = NULL;
NSArray *array = [NSArray arrayWithObjects:[[NSObject alloc] init], nil, [[NSObject alloc] init], [[NSObject alloc] init], nil];