? ? ? ? ?開(kāi)發(fā)中伪煤,weak是弱引用,weak修改的對(duì)象引用計(jì)數(shù)不會(huì)加1砖第,而且當(dāng)對(duì)象銷(xiāo)毀時(shí)候绍移,會(huì)自動(dòng)將對(duì)象指針置為nil,所以也就不會(huì)產(chǎn)生野指針了急凰。 那么weak修飾的對(duì)象底層到底做了什么呢女仰?
? ? ? ? ?首先weak底層其實(shí)是runtime,runtime維護(hù)一個(gè)全部weak修飾對(duì)象的一個(gè)hash表抡锈,其中hash表的key就是weak對(duì)象的地址疾忍,value就是指針的地址(為一個(gè)數(shù)組,因?yàn)橐粋€(gè)對(duì)象可以被多個(gè)弱引指針用指向)床三。底層實(shí)現(xiàn)分為以下三步:
? ? ? ? 1.首先初始化一罩,調(diào)用objc_initWeak函數(shù),創(chuàng)建一個(gè)新的weak指針指向?qū)ο蟮牡刂贰?/p>
? ? ? ? 2.引用的時(shí)候撇簿,objc_initWeak函數(shù)會(huì)調(diào)用objc_storeWeak函數(shù)擒抛,更新指針指向推汽,創(chuàng)建對(duì)應(yīng)的弱引用表。
? ? ? ? 3.釋放的時(shí)候歧沪,調(diào)用clearDeallocating函數(shù),該函數(shù)會(huì)根據(jù)對(duì)象的地址莲组,也就是hash表中的key诊胞,去找到對(duì)應(yīng)的value,然后遍歷置nil,然后從這個(gè)weak表中清空锹杈,最后清空對(duì)象記錄撵孤。
? ? ? ? ? 弄清楚了weak的原理,實(shí)踐中就知道為什么代理我們一般用weak修飾竭望,而不是assign修飾了吧邪码。assign一般修飾基礎(chǔ)數(shù)據(jù)類(lèi)型,如果修飾對(duì)象的話咬清,一般我們要手動(dòng)將指針收到置nil闭专,不然使用會(huì)產(chǎn)生野指針,如果在取操作該指針對(duì)應(yīng)的對(duì)象就會(huì)crash了旧烧。原因就是assign修飾對(duì)象的時(shí)候影钉,對(duì)象由于存在堆區(qū),而指針存在棧區(qū)掘剪,對(duì)象釋放后平委,系統(tǒng)不會(huì)將對(duì)應(yīng)的指針清空,所以就會(huì)造成野指針夺谁。