Objective-C內(nèi)存管理 調(diào)試內(nèi)存泄露
Objective-C內(nèi)存管理 調(diào)試內(nèi)存泄露是本文要介紹的內(nèi)容,解決內(nèi)容問(wèn)題應(yīng)該每個(gè)迭代周期要做一些壓力和內(nèi)存測(cè)試,我們先來(lái)看內(nèi)容。
1、內(nèi)存的問(wèn)題是發(fā)現(xiàn)越早,解決的代價(jià)就越小。所以最重要的是理解Objective-C內(nèi)存管理,遵循我之前提到的實(shí)踐準(zhǔn)則和編碼規(guī)范。另外,在每個(gè)迭代周期要做一些壓力和內(nèi)存測(cè)試,盡早發(fā)現(xiàn)問(wèn)題。
2、利用Clang靜態(tài)檢測(cè)工具。在XCode 3.2之后的版本里,Clang已經(jīng)被集成進(jìn)來(lái)。Build ->Build & Analyze即可運(yùn)行,它可以發(fā)現(xiàn)大部分因?yàn)槭韬鲈斐傻膬?nèi)存泄露。比如有Alloc沒(méi)有release等。下圖是一次靜態(tài)檢測(cè)的結(jié)果. 如圖所示,Clang清楚的告訴你在145行有潛在的內(nèi)存泄露,即label有alloc沒(méi)有release。(單擊放大)
圖一 Clang靜態(tài)檢測(cè)
3、如果靜態(tài)檢測(cè)工具不能解決問(wèn)題,就需要更多的分析和借助instruments工具。
(1)首先要重現(xiàn)問(wèn)題,找到是哪些操作容易產(chǎn)生內(nèi)存泄露。主要通過(guò)一些測(cè)試和推理來(lái)判斷,比如找出哪些操作重復(fù)進(jìn)行時(shí),內(nèi)存增長(zhǎng)比較明顯或者會(huì)Crash。
b)借助instruments工具。instruments是在程序運(yùn)行時(shí)在程序中注入一些代碼來(lái)動(dòng)態(tài)的檢測(cè)內(nèi)存分配狀況和泄露問(wèn)題。Run -> Run with perfomance tools - > leaks 即可啟動(dòng)。下圖是運(yùn)行l(wèi)eak instrument的一次結(jié)果,如果leak是你的代碼引起的,你還可以直接查看到引起泄露的代碼。(單擊放大)
圖二 leaked Blocks
圖三 leaked code(單擊放大)
(2)還有一個(gè)instrument叫Allocation,它可以實(shí)時(shí)監(jiān)測(cè)當(dāng)前分配了多少內(nèi)存。結(jié)合這個(gè)來(lái)進(jìn)行a)步驟的推斷,往往會(huì)比較有效??梢酝ㄟ^(guò)Run -> Run with perfomance tools - >Allocations啟動(dòng),也可以在instruments啟動(dòng)后通過(guò)window->library ->Allocations加進(jìn)來(lái)。
4、可以找你的同事codereview,旁觀者往往能發(fā)現(xiàn)問(wèn)題。有時(shí)候內(nèi)存泄露是一些理解上的誤區(qū)造成的。比如我以前一直以為 -viewDidUnload是在這個(gè)View被unload之后調(diào)用,所以我在里面做一些清理工作,比如Remove EventHandler等, 后來(lái)才知道這個(gè)函數(shù)是在內(nèi)存不足需要unload view時(shí)才被調(diào)用,這個(gè)理解誤區(qū)導(dǎo)致我花了一周的時(shí)間解決一個(gè)內(nèi)存泄露的bug。 還有一個(gè)例子,之前我的一個(gè)同事一直以為[NSDate new]是產(chǎn)生當(dāng)前時(shí)間,并不需要釋放,這也是一個(gè)比較低級(jí)的理解誤區(qū)。
5、有些內(nèi)存問(wèn)題可能是緩存引起的,并不一定是泄露。比如在Three20(Facebook IPhone Library)里,出于性能的考慮,默認(rèn)會(huì)在內(nèi)存里cache一些網(wǎng)絡(luò)圖片. [UIImage imageNamed:]也會(huì)把圖片放到system cache里面,這不能算是泄露,但有時(shí)候會(huì)引起內(nèi)存不足。
小結(jié):Objective-C內(nèi)存管理 調(diào)試內(nèi)存泄露的內(nèi)容介紹完了,希望本文對(duì)你有所幫助。