Hi父能,
本文主講,Block中使用self是牢,為何會(huì)循環(huán)依賴。
最近公司對(duì)代碼質(zhì)量很在意,這是好事华蜒。
我們使用Coverityz做了檢測(cè),的確有一大堆的問題豁遭。
So tm what叭喜!
我呢,研究各種case下的問題蓖谢,以及解決方案捂蕴。
Now譬涡,輪到了內(nèi)存泄露的case,先來搞這個(gè)Block導(dǎo)致的內(nèi)存泄露啥辨,內(nèi)存常駐吧涡匀。反正tm的都是內(nèi)存浪費(fèi)。
先來了解下溉知,啥是內(nèi)存吧陨瘩,為何泄露?
我簡(jiǎn)單搜了一下级乍,查看了該猿友的文章http://www.cnblogs.com/houjun/p/4909413.html舌劳。
通俗點(diǎn),有的區(qū)域(棧)的土地是有人管理的玫荣,會(huì)進(jìn)行回收等自動(dòng)處理甚淡,好比說該區(qū)域?qū)儆趪?guó)家,你掛了崇决,土地就回收了材诽;有的區(qū)域(堆),是公共的恒傻,誰都可以用脸侥,也沒人管理,你只享用某一塊空間盈厘,卻不管清理該空間的廢物垃圾睁枕,等你掛了,就會(huì)影響該空間的再次使用沸手。
當(dāng)然這也是計(jì)算機(jī)系統(tǒng)的機(jī)制問題外遇,在某些case下某空間無人占領(lǐng),就該清除契吉,當(dāng)然也不保證你私藏的電影會(huì)不會(huì)被清除跳仿。
回到主題,為啥內(nèi)存浪費(fèi)捐晶,該有點(diǎn)頭緒了吧菲语,就是沒人處理唄。
經(jīng)常會(huì)有人講惑灵,block中使用self會(huì)產(chǎn)生循環(huán)引用山上。
他告訴你了規(guī)則,那為何產(chǎn)生循環(huán)應(yīng)用英支?循環(huán)引用又咋了佩憾?
在下才疏學(xué)淺,也是通過查看其他猿友的文章。
http://www.cnblogs.com/biosli/archive/2013/05/29/iOS_Objective-C_Block.html
http://www.cnblogs.com/flyFreeZn/p/4264220.html
我們會(huì)想妄帘,對(duì)象都分配到棧中楞黄,就有人管理了,不會(huì)有內(nèi)存泄露的問題了寄摆,寡人只想告訴你谅辣,有想法是好的,還得按規(guī)矩來婶恼,哪種case下的對(duì)象桑阶,在哪里分配空間,是系統(tǒng)決定的勾邦。
通過其他猿友的蚣录,總結(jié)就是ARC下,就是以下兩條準(zhǔn)則來理解為啥循環(huán)依賴眷篇、為啥內(nèi)存常駐了萎河,
聲明一個(gè)block對(duì)象,它是在棧中的蕉饼;如果Block作為屬性property虐杯,默認(rèn)是strong修飾的,我們也會(huì)用copy來修飾昧港,兩種修飾擎椰,都會(huì)將Block對(duì)象 copy到堆(無人管地帶)上。
那么常見問題來了创肥,結(jié)合iOS的內(nèi)存管理機(jī)制(引用計(jì)數(shù))达舒,思路也就有了。
1叹侄、臨時(shí)定義的block巩搏,不是copy、strong出來的趾代,如果使用self贯底,不會(huì)循環(huán)依賴。
為啥咧撒强?因?yàn)閎lock中的任務(wù)結(jié)束(走完{...}),他也就會(huì)被處理干凈了丈甸,相關(guān)變量,也會(huì)清除尿褪,最主要,它在棧中得湘,不信你試試杖玲。
當(dāng)然某些case下,會(huì)延遲釋放self淘正,比如某個(gè)UIViewController的對(duì)象中摆马,你在dissmiss頁面前臼闻,使用performAfter 、dispatch_after來提交了一個(gè)任務(wù)塊(block)囤采,里面使用了self述呐,就會(huì)延遲釋放self,看個(gè)人意愿吧蕉毯,我一般在這種case下乓搬,都使用weak,來減少不必要的任務(wù)處理代虾。
2进肯、屬性block對(duì)象中,使用self棉磨,會(huì)循環(huán)依賴江掩,導(dǎo)致self不自動(dòng)釋放,導(dǎo)致內(nèi)存浪費(fèi)
為啥咧乘瓤?因?yàn)閎lock此時(shí)在堆中环形,對(duì)象self和對(duì)象block相互持有對(duì)方,導(dǎo)致彼此至少引用計(jì)數(shù)都是1衙傀,tm的誰也沒法釋放抬吟,此時(shí)最想說,真是不怕神一樣的對(duì)手差油,就怕豬一樣的隊(duì)友拗军。