1,開發(fā)中如何檢測內(nèi)存泄漏的
蘋果文檔說明 一個 app 的內(nèi)存分三類:
一種是 Leaked memory,該釋放沒有釋放,更多是發(fā)生在 MRC的時候,創(chuàng)建了忘記 release
另一種是 Abandoned memory,由于循環(huán)引用導(dǎo)致的內(nèi)存泄漏,
最后一種是 Cached memory,只是一種正常的內(nèi)存,可以重新利用,
一般解決內(nèi)存泄漏的方法有:
1> 利用 Xcode 自帶的 instruments , 但是這種方法主要應(yīng)用于解決第一種內(nèi)存泄漏,對循環(huán)引用引起的內(nèi)存泄漏沒什么作用
用法: 快捷鍵(command + i) 或者 products -> profile -> leaked
運行, 選中l(wèi)eaked checks 的 CallTree,并且在右下角勾選Invert Call Tree 和Hide System Libraries颊乘,會發(fā)現(xiàn)顯示若干行代碼禾进,雙擊即可跳轉(zhuǎn)到出現(xiàn)內(nèi)存泄漏的地方隘击,修改即可。
由于leaked 是手動檢測,所以需要手動進(jìn)行一系列操作,
2> 利用第三方框架 MLeaksFinder 來檢測 循環(huán)引用 造成的內(nèi)存泄漏,
MLeaksFinder 只能檢測出 UIViewController 和 UIView 的內(nèi)存泄漏,不過這就能應(yīng)付大多數(shù)情況了,
原理:
MLeaksFinder 從 UIViewController 入手,一般一個 UIViewController 被 pop 或者 dismiss 后,他的 view 和 view 的 subviews 也會被釋放,于是在 控制器 被 pop 或者 dismiss 一小段時間(3s)后,看看 這個控制器,他的view 和 子view是否還存在,如果還存在說明沒有釋放,
具體的做法是:為基類 NSObject 添加一個方法 - willDealloc,在這個方法中先用一個弱指針指向self, 然后利用 dispatch_after,3s后 self調(diào)用 -assertNotDealloc(這個方法的作用是直接中斷言),當(dāng),控制器被pop或者 dismiss 后,weakself 就變?yōu)?nil ,那么這個方法就不會調(diào)用, 但是如果這個方法被調(diào)用了,就說明沒有被釋放,就會中斷言
2,UIWindow的層級
UIWindow的層級由一個UIWindowLevel類型屬性windowLevel,該屬性指示了UIWindow的層級纫事,windowLevel有三種可取值矮湘。
并且層級是可以做加減的self.window.windowLevel = UIWindowLevelAlert+1;
UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal; //默認(rèn),值為0
UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert; //值為2000
UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar ; // 值為1000
Normal,StatusBar,Alert,我們看到他們?nèi)齻€層級的值依次是 0 , 1000 和 2000,也就是說 Normal 是最低級的, StatusBar 是中級的 , Alert 是最高級的, 而通常我們的界面都處于 Normal 級別(默認(rèn)),系統(tǒng)頂部的狀態(tài)欄應(yīng)該是處于中級, 提醒用戶等操作位于 Alert 級別,根據(jù)級別的優(yōu)先原則,較高的在最上面,