一、開篇
最近幾天在做APP的性能優(yōu)化問題,遇到了很多問題,所以來總結(jié)和分享一下。
內(nèi)存泄露解決分為了三步:
- 靜態(tài)分析:Instruments的Analyze。通過靜態(tài)分析我們可以最初步的了解到代碼的一些不規(guī)范的地方和一些代碼邏輯上的錯(cuò)誤;
- 解決ViewController不釋放的問題;
- Instruments的Leaks。運(yùn)行時(shí)分析內(nèi)存泄露情況并解決;
根據(jù)這三步的解決內(nèi)存泄露問題,每一步包含的內(nèi)容比較多,所以我分為三篇文章來寫。
這篇文章是總結(jié)靜態(tài)分析代碼的時(shí)候遇到的常見的幾類問題,及解決方法。首先會(huì)介紹下內(nèi)存泄露相關(guān)的基礎(chǔ)知識。
二、內(nèi)存泄露相關(guān)的基礎(chǔ)知識
1.概念
內(nèi)存泄露:如果程序運(yùn)行時(shí)一直分配內(nèi)存而不及時(shí)釋放無用的內(nèi)存,程序占用的內(nèi)存越來越大,直到把系統(tǒng)分配給該APP的內(nèi)存消耗殫盡,程序因無內(nèi)存可用導(dǎo)致崩潰,這樣的情況我們稱之為內(nèi)存泄漏。
2. 可能引起的問題
1)內(nèi)存消耗殆盡的時(shí)候,程序會(huì)因沒有內(nèi)存被殺死,即crash。
2)當(dāng)內(nèi)存快要用完的時(shí)候,會(huì)非常的卡頓
3)如果是ViewController沒有釋放掉,引起的內(nèi)存泄露,還會(huì)引起其他很多問題,尤其是和通知相關(guān)的。沒有被釋放掉的ViewController還能接收通知,還會(huì)執(zhí)行相關(guān)的動(dòng)作,所以會(huì)引起各種各樣的異常情況的發(fā)生。
三、Analyze檢測出的幾種常見問題
使用Analyze能夠發(fā)現(xiàn)一些代碼不規(guī)范的地方。下面是我調(diào)試的過程中遇到的一些問題。
-
value stored to ‘width’during its initialization is never read。
該問題的原因是:變量申請了內(nèi)存并初始化了,但沒有用使此變量,接著將此變量又從新賦值. - (CGSize)sizeForContent:(MGCMessageBaseEntity*)message { float width = size.width < 20 ? 20 : size.width + 5; width = size.width > MAX_CHAT_TEXT_WIDTH ? MAX_CHAT_TEXT_WIDTH : size.width; return CGSizeMake(width, size.height + 3); } 規(guī)范的寫法是:float width = size.width > MAX_CHAT_TEXT_WIDTH ? MAX_CHAT_TEXT_WIDTH : size.width; 還有一種情況是:為同一個(gè)數(shù)據(jù)源分配了兩塊內(nèi)存,這里不會(huì)引起內(nèi)存泄露,因?yàn)闉閍rr1分配的內(nèi)存塊雖然一直是空閑塊,但是在生命周期結(jié)束時(shí),這塊內(nèi)存會(huì)被釋放掉。跟前面說的,內(nèi)存泄露是內(nèi)存一直得不到釋放,才會(huì)造成內(nèi)存泄露。 NSArray *arr1 = [[NSArray alloc]init]; if(index == 1){ arr1 = self.usersArray; }else{ arr1 = self.editArray; } 因?yàn)閟elf.usersArray和self.editArray都是被初始化過的數(shù)組,將它們賦值給了arr1,arr1又申請了內(nèi)存。規(guī)范的寫法是:NSArray *arr1;不為arr1分配內(nèi)存。
-
Value stored to 'titleString' is never read
該變量從來沒有被使用
-
Potential leak of an object allocated on line 101 and stored into ''
潛在的內(nèi)存泄露:這里主要是一些非OC對象,ARC不會(huì)對它進(jìn)行釋放,所以造成了一直沒有釋放。比如一些類型:CGImageRef(對應(yīng)調(diào)用CGImageRelease)、CGContextRef(對應(yīng)調(diào)用CGContextRelease)CGColorSpaceRef(對應(yīng)CGColorSpaceRelease) 這些都是非OC對象,所以要自己記著釋放掉。
Analyze還能檢查出一些邏輯上的錯(cuò)誤,并且指出原因,簡直太好用了。不出例子了,因?yàn)榇a已經(jīng)解決了好幾天了,現(xiàn)在不存在有邏輯錯(cuò)誤的代碼了。