ARC環(huán)境的內(nèi)存問(wèn)題

一、僵尸對(duì)象問(wèn)題

在MRC環(huán)境下,我們經(jīng)常會(huì)碰到message sent to deallocated instance 的錯(cuò)誤,這個(gè)錯(cuò)誤的名稱為 EXC_BAD_ACCESS , 多發(fā)生在對(duì)一個(gè)對(duì)象重復(fù)release 而過(guò)度釋放的情況下,也就是所謂的僵尸對(duì)象(NSZombie Object),有時(shí)候也稱作野指針問(wèn)題(指針指向的是僵尸對(duì)象)。自從ios 5.0推出以后,大多數(shù)程序都切換到了ARC環(huán)境,這一類的錯(cuò)誤也少了很多。但是他們并沒(méi)有完全消失,仍然存在于代碼中。下面舉出幾個(gè)常見(jiàn)的例子:

?1. ?委托對(duì)象未置空,常見(jiàn)的如UITableView,UIWebView。

? ? ?這一類控件的委托是異步執(zhí)行的,而且由于年代久遠(yuǎn),他們的delegate 屬性還是assign,而不是現(xiàn)在常用的weak。這就存在一個(gè)問(wèn)題,如果頁(yè)面正在加載數(shù)據(jù),其委托對(duì)象為self , 這時(shí)候頁(yè)面突然退出,委托指向的VC被釋放,而tableView或者webView的delegate沒(méi)有置空,就有可能觸發(fā)僵尸對(duì)象問(wèn)題。正確的解決方法是在頁(yè)面dealloc或者viewWillDisappear的時(shí)候?qū)elegate及時(shí)置空。

2. 注冊(cè)通知后沒(méi)有在dealloc中反注冊(cè)。

? ? ?這個(gè)情況多發(fā)生于VC中,init或viewDidload時(shí)注冊(cè)了通知監(jiān)聽(tīng),但在dealloc時(shí)沒(méi)有反注冊(cè),導(dǎo)致VC釋放以后通知中心仍然保持著對(duì)VC的引用,也就形成了僵尸對(duì)象,當(dāng)相關(guān)通知發(fā)出時(shí),就會(huì)因?yàn)橐爸羔樁罎?。解決方法是在dealloc 時(shí)反注冊(cè)通知監(jiān)聽(tīng)。

二、循環(huán)引用問(wèn)題

1. 委托使用了strong屬性,導(dǎo)致委托對(duì)象和被委托的對(duì)象之間形成循環(huán)引用。

2. block中引用了self,而self沒(méi)有使用weak屬性修飾。由于眾所周知的原因,block會(huì)對(duì)他里面的對(duì)象強(qiáng)引用,而被他引用的對(duì)象如果又持有這個(gè)block,就會(huì)形成循環(huán)引用。

3. 定時(shí)器。由于定時(shí)器在創(chuàng)建時(shí)會(huì)對(duì)指定的target強(qiáng)引用,如果target恰好又是定時(shí)器的持有者時(shí),就形成了循環(huán)引用。

4. JavascriptCore的循環(huán)引用。

? ?如果你的代碼中有對(duì)象(我們暫命名為JSListener)持有了 JSContext,同時(shí)該對(duì)象又實(shí)現(xiàn)了JSExport協(xié)議,那么就很有可能形成JSContext與JSListener的循環(huán)引用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容