起因
最近上海這邊做了一個項(xiàng)目匿值,由于上海的同事幾乎沒有工作經(jīng)驗(yàn)窍仰,代碼寫得很亂砍的,沒有規(guī)范歧焦。應(yīng)用在客戶測試時出現(xiàn)各種問題蟆豫,甚至是一些致命性的閃退問題丐一,同事求助于我對代碼做一些檢查凫岖。發(fā)現(xiàn)現(xiàn)在學(xué)習(xí)IOS開發(fā)的人火邓,自從有了ARC之后對內(nèi)存管理完全沒有概念飞崖。以為啥都不用管烂叔。
常見的哪些情況下會系統(tǒng)不會釋放內(nèi)存
NSTimer
NSTimer 在使用當(dāng)中有這些情況,當(dāng)你在ViewController中創(chuàng)建后固歪,如果沒有invalidate
他的執(zhí)行蒜鸡,那么他會一直不停的執(zhí)行胯努。當(dāng)ViewController 在 disMissModal
后,這個ViewController一直都會保留在內(nèi)存中逢防, 如果應(yīng)用的內(nèi)存使用沒有超過20M的時候叶沛,dealloc
是永遠(yuǎn)都不會調(diào)用的,也意味著這個ViewController是一直都沒有被釋放忘朝,當(dāng)app內(nèi)存超過20M時 dealloc
可能會突然強(qiáng)制執(zhí)行灰署,但是執(zhí)行也是不正常的。
NSTimer的關(guān)閉一定不能放在dealloc
局嘁,而是要在界面退出前執(zhí)行溉箕,比如dismissModal
或者 popViewController
之前
Block
Block內(nèi)部使用一個實(shí)例時會retain
,為了防止內(nèi)存泄露悦昵。在block之前需使用__weak
引用標(biāo)示肴茄。MRC 中要使用 __block
ARC
__weak CurrentViewController* blockSelf = self;
brush.getCardInfo=^(NSDictionary *info){
[blockSelf test];
};
循環(huán)參照 [1]
A有個屬性參照B,B有個屬性參照A但指,如果都是strong參照的話寡痰,兩個對象都無法釋放。
這種問題常發(fā)生于把delegate聲明為strong屬性了棋凳。
例
@interface SampleViewController
@property (nonatomic, strong) SampleClass *sampleClass;
@end
@interface SampleClass
@property (nonatomic, strong) SampleViewController *delegate;
@end
上例中拦坠,解決辦法是把SampleClass 的delegate屬性的strong改為assign即可。
死循環(huán)
如果某個ViewController中有無限循環(huán)剩岳,也會導(dǎo)致即使ViewController對應(yīng)的view關(guān)掉了贞滨,ViewController也不能被釋放。
這種問題常發(fā)生于animation處理卢肃。
比如疲迂,
CATransition *transition = [CATransition animation];
transition.duration = 0.5;
tansition.repeatCount = HUGE_VALL;
[self.view.layer addAnimation:transition forKey:"myAnimation"];
上例中,animation重復(fù)次數(shù)設(shè)成HUGE_VALL莫湘,一個很大的數(shù)值尤蒿,基本上等于無限循環(huán)了。
解決辦法是幅垮,在ViewController關(guān)掉的時候腰池,停止這個animation。
-(void)viewWillDisappear:(BOOL)animated {
[self.view.layer removeAllAnimations];
}
內(nèi)存泄露的情況當(dāng)然不止以上幾種忙芒。
即使用了ARC示弓,我們也要深刻理解iOS的內(nèi)存管理機(jī)制,這樣才能有效避免內(nèi)存泄露呵萨。
關(guān)于內(nèi)存是否泄露的檢查和排除
以上幾種情況可能通過instrument 是查看不出來的奏属,排查的方法也很簡單,我們只要在每個相關(guān)的Class中實(shí)現(xiàn) dealloc
方法潮峦,加上日志囱皿,看他是否有執(zhí)行就有可以了勇婴。