起因
最近上海這邊做了一個(gè)項(xiàng)目,由于上海的同事幾乎沒有工作經(jīng)驗(yàn),代碼寫得很亂,沒有規(guī)范。應(yīng)用在客戶測試時(shí)出現(xiàn)各種問題,甚至是一些致命性的閃退問題,同事求助于我對代碼做一些檢查。發(fā)現(xiàn)現(xiàn)在學(xué)習(xí)IOS開發(fā)的人,自從有了ARC之后對內(nèi)存管理完全沒有概念。以為啥都不用管。
常見的哪些情況下會(huì)系統(tǒng)不會(huì)釋放內(nèi)存
NSTimer
NSTimer 在使用當(dāng)中有這些情況,當(dāng)你在ViewController中創(chuàng)建后,如果沒有invalidate
他的執(zhí)行,那么他會(huì)一直不停的執(zhí)行。當(dāng)ViewController 在 disMissModal
后,這個(gè)ViewController一直都會(huì)保留在內(nèi)存中, 如果應(yīng)用的內(nèi)存使用沒有超過20M的時(shí)候,dealloc
是永遠(yuǎn)都不會(huì)調(diào)用的,也意味著這個(gè)ViewController是一直都沒有被釋放,當(dāng)app內(nèi)存超過20M時(shí) dealloc
可能會(huì)突然強(qiáng)制執(zhí)行,但是執(zhí)行也是不正常的。
NSTimer的關(guān)閉一定不能放在dealloc
,而是要在界面退出前執(zhí)行,比如dismissModal
或者 popViewController
之前
Block
Block內(nèi)部使用一個(gè)實(shí)例時(shí)會(huì)retain
,為了防止內(nèi)存泄露。在block之前需使用__weak
引用標(biāo)示。MRC 中要使用 __block
ARC
__weak CurrentViewController* blockSelf = self;
brush.getCardInfo=^(NSDictionary *info){
[blockSelf test];
};
循環(huán)參照 [1]
A有個(gè)屬性參照B,B有個(gè)屬性參照A,如果都是strong參照的話,兩個(gè)對象都無法釋放。
這種問題常發(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)
如果某個(gè)ViewController中有無限循環(huán),也會(huì)導(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,一個(gè)很大的數(shù)值,基本上等于無限循環(huán)了。
解決辦法是,在ViewController關(guān)掉的時(shí)候,停止這個(gè)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 是查看不出來的,排查的方法也很簡單,我們只要在每個(gè)相關(guān)的Class中實(shí)現(xiàn) dealloc
方法,加上日志,看他是否有執(zhí)行就有可以了。