iOS APP內(nèi)存泄露問題解決(二)

一李请、問題描述

ViewController不釋放藤抡,會(huì)導(dǎo)致很多問題辫封,我舉幾個(gè)我遇到的例子硝枉。

  1. 我做的是一個(gè)企業(yè)即時(shí)通訊APP,我做了一個(gè)群公告功能倦微,發(fā)布群公告時(shí)會(huì)發(fā)送@all消息妻味。某天,我做完了群公告欣福,發(fā)了一個(gè)群公告試試责球,結(jié)果,消息群發(fā)了拓劝,發(fā)到了好幾個(gè)聊天會(huì)話中去了雏逾。因?yàn)閏hattingViewController沒有釋放掉,發(fā)送@all消息的通知郑临,那些沒有被釋放掉的chattingViewController都收到了栖博,都執(zhí)行了發(fā)送@all消息的動(dòng)作,所以導(dǎo)致很多會(huì)話都發(fā)送了@all消息厢洞。
  2. 我做一個(gè)踢出登錄的功能笛匙,退到登錄頁(yè)面的時(shí)候,之前的主界面都沒有被釋放犀变,踢出登錄會(huì)發(fā)一個(gè)通知妹孙,顯示一個(gè)alert:你被踢出登錄。多次被踢出获枝,就會(huì)創(chuàng)建多個(gè)主界面蠢正,多個(gè)主界面都會(huì)收到這個(gè)通知,于是就顯示了多個(gè)alertView省店。
  3. NSTimer嚣崭,NSTimer會(huì)對(duì)它的target持有強(qiáng)引用,如果NSTimer不釋放掉懦傍,就會(huì)一直持有它的target的強(qiáng)引用雹舀,會(huì)一直都釋放不掉,造成內(nèi)存泄露粗俱。

二说榆、解決方法

怎么知道ViewController有沒有被釋放,有一個(gè)方法就是可以通過看ViewController有沒有執(zhí)行dealloc方法。
大概有幾個(gè)地方签财,比較容易引起內(nèi)存泄露

  1. 循環(huán)引用串慰;最多的就是block引起的循環(huán)引用。
    (1)某個(gè)類將block作為自己的屬性變量唱蒸,然后該類在block的方法體里面又使用了該類本身;相互持有邦鲫,導(dǎo)致都釋放不了。

     代碼例子:
     [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
     make.left.right.equalTo(self.view);
     make.top.equalTo(self.navigationBar.mas_bottom);
     make.bottom.equalTo(self.view);
     }];
     修改為:
     __weak typeof(self) weakSelf = self;
     塊內(nèi)的self神汹,換成weakSelf就行了庆捺。
     block不是self的屬性或者變量時(shí),在block內(nèi)使用self不會(huì)循環(huán)引用;
     
     (2)如果塊是一個(gè)單例持有的屁魏,塊內(nèi)又使用了ViewController這個(gè)類滔以,會(huì)引起循環(huán)引用。     
     例子:
     [[OutsidePacketsSchedule shareInstance] sendParameters:dict requestCmd:@"addCustomEmoReq" responseCmd:@"addCustomEmoRsp" complete:^(id response, NSError *error) {
     if(!error){
         [weakSelf.view setToast:@"添加自定義表情成功"];
     }
     }];
     上例中的單例持有的代碼塊中要用弱引用蚁堤,原因是:?jiǎn)卫粫?huì)被釋放掉,它會(huì)一直持有block但狭,導(dǎo)致該block所在的ViewController釋放不掉披诗。
     (3)如果是方法中的參數(shù)是block,不會(huì)造成循環(huán)引用立磁,因?yàn)榉椒ㄖ械腷lock是位于棧內(nèi)存的呈队,方法返回后,block將會(huì)無效唱歧。
    
  2. NSTimer和CADisplayLink這種宪摧;
    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti
    target:(id)aTarget
    selector:(SEL)aSelector
    userInfo:(nullable id)userInfo
    repeats:(BOOL)yesOrN{

    }
    從文檔中方法的定義上可以看到,NSTimer是會(huì)強(qiáng)引用它的target的颅崩,像其他的delegate一般都是weak的几于,所以這里比較特殊。
    NSTimer Class Reference是這樣對(duì)target描述的:
    The object to which to send the message specified by aSelector when the timer fires. The timer maintains a strong reference to target until it (the timer) is invalidated.
    NSTimer Class Reference還指出: Runloop會(huì)強(qiáng)引用timer沿后,因?yàn)槿绻粋€(gè)timer是循環(huán)的沿彭,如果沒被強(qiáng)引用,那么在函數(shù)返回后尖滚,則會(huì)被銷毀喉刘,就不能循環(huán)地通知持有的target。所以NSTimer是被放到Runloop中執(zhí)行的漆弄。
    如果我們不調(diào)用invalidate timer,runloop就會(huì)一直持有timer,而timer也一直持有ViewController睦裳,這樣就會(huì)造成內(nèi)存泄露。
    
    解決這類問題的方法就是:在不需要NSTimer的時(shí)候撼唾,及時(shí)調(diào)用[self.timer invalidate]廉邑。千萬不要在dealloc方法中調(diào)用,因?yàn)镹STimer強(qiáng)引用self,所以不會(huì)執(zhí)行dealloc方法鬓催。
    
  3. delegate一般是weak的情況分析肺素;
    這里我遇到的情況,在我的第一篇博客里面有寫到宇驾,感興趣的可以去看一下倍靡。

  4. 對(duì)象之間的循環(huán)引用:例子:兩個(gè)ViewController都需要使用對(duì)方,這個(gè)時(shí)候可以用@class

  5. 是我解決ViewController不釋放的時(shí)候遇到的一個(gè)個(gè)例問題课舍,當(dāng)時(shí)把ViewController里的每行代碼都分析了塌西,強(qiáng)引用的地方都解決了,還是不執(zhí)行dealloc方法筝尾,查了好久捡需,請(qǐng)教了好幾個(gè)同事,最后筹淫,發(fā)現(xiàn)站辉,竟然是這個(gè)ViewController沒有開啟ARC,不知道是被那個(gè)隊(duì)友給關(guān)閉了损姜,哭瞎=饰剥。=

三、最后的建議

上文中我主要是根據(jù)自己在項(xiàng)目中遇到的問題摧阅,及如何解決的汰蓉,來描述的。不是很詳細(xì)深入棒卷,這里建議多看一下官方文檔顾孽,一般的問題都可以通過閱讀官方文檔來解決的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末比规,一起剝皮案震驚了整個(gè)濱河市若厚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蜒什,老刑警劉巖盹沈,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異吃谣,居然都是意外死亡乞封,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門岗憋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肃晚,“玉大人,你說我怎么就攤上這事仔戈」卮” “怎么了拧廊?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)晋修。 經(jīng)常有香客問我吧碾,道長(zhǎng),這世上最難降的妖魔是什么墓卦? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任倦春,我火速辦了婚禮,結(jié)果婚禮上落剪,老公的妹妹穿的比我還像新娘睁本。我一直安慰自己,他們只是感情好忠怖,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布呢堰。 她就那樣靜靜地躺著,像睡著了一般凡泣。 火紅的嫁衣襯著肌膚如雪枉疼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天鞋拟,我揣著相機(jī)與錄音骂维,去河邊找鬼。 笑死严卖,一個(gè)胖子當(dāng)著我的面吹牛席舍,可吹牛的內(nèi)容都是我干的布轿。 我是一名探鬼主播哮笆,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼汰扭!你這毒婦竟也來了稠肘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤萝毛,失蹤者是張志新(化名)和其女友劉穎项阴,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笆包,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡环揽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了庵佣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歉胶。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖巴粪,靈堂內(nèi)的尸體忽然破棺而出通今,到底是詐尸還是另有隱情粥谬,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布辫塌,位于F島的核電站漏策,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏臼氨。R本人自食惡果不足惜掺喻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望一也。 院中可真熱鬧巢寡,春花似錦、人聲如沸椰苟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)舆蝴。三九已至谦絮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間洁仗,已是汗流浹背层皱。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赠潦,地道東北人叫胖。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像她奥,于是被迫代替她去往敵國(guó)和親瓮增。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容