iOS八種內(nèi)存泄漏問題

循環(huán)引用(Retain Cycle)

先簡單說一下什么是循環(huán)引用(retain cycle)
?假設(shè)我們有兩個實例A和B甫窟,B是A的一個strong型的property径密,則B的引用計數(shù)是1,當(dāng)A的需要釋放的時候,A則會調(diào)用[B release]來釋放B,B的引用計數(shù)則減為0快毛,釋放。

?可如果這時候?qū)的一個strong型property指向A番挺,則A與B互相為強引用唠帝,問題就來了。因為B強引用A建芙,A的引用計數(shù)永遠(yuǎn)不會減為0没隘,當(dāng)A原本的強引用對象被釋放以后,A和B成為了一個相互引用的孤島禁荸,永遠(yuǎn)不會被釋放了右蒲,這就會引起內(nèi)存泄漏。

?在上面的例子中赶熟,就是一種非常普遍的引用循環(huán)情況瑰妄,加入如上代碼的VC在dismiss或者pop以后,并不會執(zhí)行dealloc方法映砖,證明內(nèi)存泄漏了间坐。而引起泄漏的原因就是在作為self的property的block中,使用self指針導(dǎo)致self被block強引用,形成引用循環(huán)竹宋。

總結(jié)一下出現(xiàn)內(nèi)存泄漏的幾種常見情況

1劳澄、Delegate/NSNotification

我們在使用代理設(shè)計模式的時候,一定要注意將 delegate 變量聲明為 weak 類型蜈七,像這樣
如使用strong或別的類型修飾的話將會導(dǎo)致循環(huán)引用秒拔,導(dǎo)致dealloc()不會被調(diào)用。NSNotification沒有移除通知等都會觸發(fā)一些意想不到的后果飒硅。

2砂缩、Block

目前在項目中出現(xiàn)的內(nèi)存泄漏大部分是因為block的問題。
在 ARC 下三娩,當(dāng) block 獲取到外部變量時庵芭,由于編譯器無法預(yù)測獲取到的變量何時會被突然釋放,為了保證程序能夠正確運行雀监,讓 block 持有獲取到的變量双吆,向系統(tǒng)聲明:我要用它,你們千萬別把它回收了滔悉!然而伊诵,也正因 block 持有了變量单绑,容易導(dǎo)致變量和 block 的循環(huán)引用回官,造成內(nèi)存泄露

[_sortButton setButtonSpreadPreAction:^BOOL{
    if (_resultItems.count == 0) {
        [progressHUD showText:@"xxxx"];
        return NO;
    }
    return YES;
}];

這個例子的問題就在于在使用 block 的過程中形成了循環(huán)引用:self 持有 sortButton;sortButton 持有 block搂橙;block 持有 self歉提。三者形成循環(huán)引用,內(nèi)存泄露区转。

GCD已經(jīng)一些系統(tǒng)級的API并不會提示循環(huán)引用的警告苔巨,但通過測試發(fā)現(xiàn),大部分系統(tǒng)提供block也是需要弱引用的__weak typeof(self) weakSelf = self;
項目中除了AFN的第三方組件在調(diào)用block時都是需要弱引用的废离。

3侄泽、NSTimer

?NSTimer在釋放前,一定要調(diào)用[timer invalidate]蜻韭,不調(diào)用的后果就是NSTimer無法釋放其target悼尾,如果target正好是self,則會導(dǎo)致引用循環(huán)肖方。
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay

官方文檔是這樣說的:

This method sets up a timer to perform the aSelector message on the current thread’s run loop. The timer is configured to run in the default mode (NSDefaultRunLoopMode). When the timer fires, the thread attempts to dequeue the message from the run loop and perform the selector. It succeeds if the run loop is running and in the default mode; otherwise, the timer waits until the run loop is in the default mode.

大概意思是系統(tǒng)依靠一個timer來保證延時觸發(fā)闺魏,但是只有在runloop在default mode的時候才會執(zhí)行成功,否則selector會一直等待run loop切換到default mode俯画。根據(jù)我們之前關(guān)于timer
的說法析桥,在這里其實調(diào)用performSelector:afterDelay:同樣會造成系統(tǒng)對target強引用,也即retain住。這樣子泡仗,如果selector一直無法執(zhí)行的話(比如runloop不是運行在default model下),這樣子同樣會造成target一直無法被釋放掉埋虹,發(fā)生內(nèi)存泄露。怎么解決這個問題呢娩怎?其實很簡單吨岭,我們在適當(dāng)?shù)臅r候取消掉該調(diào)用就行了,系統(tǒng)提供了接口:

+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget

?這里要補充一點峦树,引用循環(huán)不是只能有兩個對象辣辫,三個四個更多都是可以的,甚至環(huán)數(shù)也不一定只有一個魁巩,所以要養(yǎng)成良好的代碼習(xí)慣急灭,在NSTimer停用前調(diào)用invalidate方法。

4谷遂、Image內(nèi)存過大

圖片造成內(nèi)存泄漏的案例

5葬馋、Foundation與CoreFoundation的相互引用也會造成內(nèi)存泄漏

6.AFN 的NSURLSession不能釋放

//解決辦法:
//修改AFHTTPSessionManager 的manager方法,替換manager;
//或繼承其肾扰,自己寫個manager方法
//另一種寫法畴嘶,兩個單例:
+ (AFHTTPSessionManager *)sharedHTTPSession{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    manager = [AFHTTPSessionManager manager];
    manager.requestSerializer.timeoutInterval = 30;
    [manager.requestSerializer  setValue:@"XMLHttpRequest" 
forHTTPHeaderField:@"X-Requested-With"];
});
return manager;
}
+ (AFURLSessionManager *)sharedURLSession{
static dispatch_once_t onceToken2;
dispatch_once(&onceToken2, ^{
    urlsession = [[AFURLSessionManager alloc] initWithSessionConfiguration:
[NSURLSessionConfiguration defaultSessionConfiguration]];
});
return urlsession;
}

7.UIWebView 不能釋放

目前只能用WKWebView 了。其他方法試了下集晚,都沒什么用
WKWebview也會造成內(nèi)存泄漏窗悯,在OC與JS互相調(diào)用時,
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;
如果不remove掉會使得此VC不走dealloc

感謝微辣小龍蝦的指點

8.友盟分享(無解)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末偷拔,一起剝皮案震驚了整個濱河市蒋院,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌莲绰,老刑警劉巖欺旧,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蛤签,居然都是意外死亡辞友,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門震肮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來称龙,“玉大人,你說我怎么就攤上這事钙蒙∫鹌伲” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵躬厌,是天一觀的道長马昨。 經(jīng)常有香客問我竞帽,道長,這世上最難降的妖魔是什么鸿捧? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任屹篓,我火速辦了婚禮,結(jié)果婚禮上匙奴,老公的妹妹穿的比我還像新娘堆巧。我一直安慰自己,他們只是感情好泼菌,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布谍肤。 她就那樣靜靜地躺著,像睡著了一般哗伯。 火紅的嫁衣襯著肌膚如雪荒揣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天焊刹,我揣著相機與錄音系任,去河邊找鬼。 笑死虐块,一個胖子當(dāng)著我的面吹牛俩滥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播贺奠,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼霜旧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了敞嗡?” 一聲冷哼從身側(cè)響起颁糟,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤航背,失蹤者是張志新(化名)和其女友劉穎喉悴,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玖媚,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡箕肃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了今魔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片勺像。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖错森,靈堂內(nèi)的尸體忽然破棺而出吟宦,到底是詐尸還是另有隱情,我是刑警寧澤涩维,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布殃姓,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蜗侈。R本人自食惡果不足惜篷牌,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望踏幻。 院中可真熱鬧枷颊,春花似錦、人聲如沸该面。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽隔缀。三九已至听诸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蚕泽,已是汗流浹背晌梨。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留须妻,地道東北人仔蝌。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像荒吏,于是被迫代替她去往敵國和親敛惊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

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

  • 內(nèi)存管理 簡述OC中內(nèi)存管理機制绰更。與retain配對使用的方法是dealloc還是release瞧挤,為什么?需要與a...
    丶逐漸閱讀 1,964評論 1 16
  • # 前言 反復(fù)地復(fù)習(xí)iOS基礎(chǔ)知識和原理儡湾,打磨知識體系是非常重要的特恬,本篇就是重新溫習(xí)iOS的內(nèi)存管理。 內(nèi)存管理是...
    Vein_閱讀 796評論 0 2
  • 目錄 屬性 修飾詞 循環(huán)引用 typeof與typedef 1. 屬性 objc所有類和對象都是c結(jié)構(gòu)體徐钠,cate...
    Ryan___閱讀 355評論 0 1
  • 《Objective-C高級編程》這本書就講了三個東西:自動引用計數(shù)癌刽、block、GCD尝丐,偏向于從原理上對這些內(nèi)容...
    WeiHing閱讀 9,812評論 10 69
  • ARC下的內(nèi)存泄漏 ARC全稱叫 ARC(Automatic Reference Counting)显拜。在編譯期間,...
    瞇大帥閱讀 1,172評論 1 51