1. 程式人生 > >Instruments使用之使用Leaks檢測記憶體洩漏

Instruments使用之使用Leaks檢測記憶體洩漏

上一篇文章我介紹了Instruments的工具分類和基本使用方法,今天我再來給大家說說Leaks的使用方法。

在早期的iOS開發中,並沒有ARC模式,只有MRC模式,必須由開發人員自己管理記憶體,過程非常繁瑣而且容易造成記憶體洩漏,如今的iOS開發雖然基本都是用的ARC模式,但是有些情況下還是需要我們自己來管理記憶體,稍有不慎,就可能造成記憶體洩漏,所以,使用一款記憶體洩漏的檢測工具還是非常有必要的。

接下來咱們就一起看看Leaks這個工具的使用方法。

第一步:新建一個工程,名字隨便取。

在MRC模式下,咱們可以隨便宣告類的物件然後不釋放,造成記憶體洩漏的問題,但是今天咱們在ARC模式看看記憶體洩漏是如何出現的大笑

大笑

建好工程,Device選項選擇自己的iPhone(選擇真機),然後咱們開啟Instruments(command+i)(你會發現自己手機上多出一個工程,工程名就是你剛才建立的工程),在Instruments工具中選擇Leaks,開啟Leaks。

第二步:開始除錯。

執行工程,此時Xcode可能會彈出下面這個東東


不要害怕,它只是告訴咱們,請在你的裝置上信任這個應用

步驟:開啟設定->通用->裝置管理->你的開發者賬號->信任這個賬號

OK,信任完畢,然後再執行工程,沒問題了!

接著開始使用Leaks,工程中 command+control+i開啟它,執行一段時間後我們會發現下面這張圖所示的情況,有很多綠背景的“對號”。這些對號代表沒有記憶體洩漏,因為咱們緊緊打開了一個系統預設的第一主視窗。


接下來咱們就可以手動新增一些可以造成記憶體洩漏的程式碼了

先建立第二個檢視控制器SecondViewController,然後在storyboard中給第一個控制器介面新增一個按鈕,點選跳進第二個檢視控制器(ps:不會使用storyboard?請我吃飯我告訴你微笑


在第二個檢視控制器的viewDidLoad方法中新增bug程式碼

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef colorRef = CGColorCreate(colorSpace, (CGFloat[]){1, 0, 0, 0.8});
UIColor *color = [UIColor colorWithCGColor:colorRef];
self.view.backgroundColor = color;


很明顯,沒有釋放colorRef,接下來測試一下。

執行工程,然後command+control+i,這時Leaks會自動重新執行iPhone上的工程並開始記錄資料

點選按鈕進入第二個介面,讓bug程式碼走一遍,再點選空白返回上個介面,我們會看到有一個紅色背景的“叉符號”,這個就代表記憶體洩漏


點選暫停,將滑鼠移到叉號上面點選鎖定。


點選下方的“田”字格,選擇callTree


找到右下角工具區域上面 三個圖示 的地方,選擇中間的齒輪“⚙”

選中選項中的 invert Call Tree 和Hide System Libraries


雙擊左邊 Call Tree 下面的任意一行,檢視記憶體洩漏的程式碼位置


問題出現了!!!沒有顯示程式碼位置!大笑不要慌,這是因為我們沒有設定一個選項

找到工程中的 Build Settings ,輸入 options 查詢,在Build Options 欄目下方找到 Debug Information Format,將其屬性設定為 DWARF with dSYM File


為什麼要這麼做呢?

因為 Symbol Name 一欄 下面的 0x1000ea6cb與0x1000ea8c7 是記憶體地址,可是這東西對我來毫無用處。Xcode編譯專案後,我們會看到一個同名的 dSYM 檔案,dSYM 是儲存 16 進位制函式地址對映資訊的中轉檔案,我們除錯的 symbols 都會包含在這個檔案中,並且每次編譯專案的時候都會生成一個新的 dSYM 檔案。途中顯示0x1000ea6cb與0x1000ea8c7 是因為我們的工程 Build Settings 的問題,沒有生成dSYM 檔案,也就無法解析debug symbols。當我們設定為生成dSYM檔案 後,就可以檢視對應的程式碼位置資訊了。

接下來重新執行工程,重新執行Leaks,重新點選按鈕填入第二個控制器執行 bug程式碼,重新確定記憶體洩漏、切換為 Call Tree,雙擊問題欄進入程式碼位置


終於發現原因啦大笑我們的colorRef變數沒有釋放,那我們就新增一行程式碼就可以了:CGColorRelease(colorRef);

再次測試之後發現已經沒有記憶體洩漏的問題了!


然而並不是所有的記憶體洩漏都會被檢測出來,下面這個情況我覺得可以作為典型的事例說一下。

使用定時器,迴圈列印一句話,在dealloc方法中列印資訊觀察物件是否真的被釋放。


重複上面的測試過程,我們看到了不好的畫面。

列印資訊顯示控制器dismiss後沒有釋放,Leaks卻沒有測出來記憶體洩漏!


所以,作為程式猿,咱們最好還是多重視基礎,完善自我,這樣才能更好地設計出趨於完美的程式微笑微笑

不好意思又說教了哈大笑,大家不要在意。

圖中出現的私人資訊禁止惡意傳播,圖片不允許隨意使用,大家諒解哈。

如果你覺得我寫得還湊合,就在下面的兩個選項中選擇  “頂”  我一下吧!