自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

詳解iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引

移動(dòng)開(kāi)發(fā) iOS
iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引是本文要要介紹的內(nèi)容,主要是倆學(xué)習(xí)iphone應(yīng)用內(nèi)存的管理,來(lái)看本文詳解。

iPhone應(yīng)用內(nèi)存泄露使用Leaks工具指引是本文要要介紹的內(nèi)容,主要是倆學(xué)習(xí)iphone應(yīng)用內(nèi)存的管理。最近常使用Instruments這個(gè)工具,我發(fā)現(xiàn)它對(duì)追蹤游戲中的內(nèi)存泄露非常有幫助。自從發(fā)現(xiàn)Instruments如此有用后,我就覺(jué)得寫(xiě)一篇文章介紹如何使用它來(lái)追蹤內(nèi)存泄露對(duì)其他人也會(huì)有幫助。

什么是內(nèi)存泄露?我為什么要關(guān)心內(nèi)存泄露?

…此段省略…

訪問(wèn)維基百科可以獲得更多關(guān)于內(nèi)存泄露的信息。

我如何知道內(nèi)存泄露了?

一些內(nèi)存泄露可以很容易地通過(guò)閱讀代碼來(lái)發(fā)現(xiàn),另一些就要困難點(diǎn)了,這就是為什么需要Instruments 的原因。Instruments 有一個(gè)“Leaks工具”,它會(huì)準(zhǔn)確地告訴你什么地方發(fā)生了內(nèi)存泄露,以便你能定位和修復(fù)泄露問(wèn)題。

例子程序

我寫(xiě)了一個(gè)例子程序,它有兩個(gè)地方會(huì)發(fā)生內(nèi)存泄露,一個(gè)在 Objective-C 視圖控制器中,另一個(gè)在 C++ 類(lèi)中。例程可以從這里獲得。下邊的代碼是從例程里摘錄的,包含了我們需要追蹤內(nèi)存泄露的代碼。

  1. // Leaky excerpts – see GitHub for complete source  
  2.  
  3. - (void)viewDidLoad {  
  4. [super viewDidLoad];  
  5.  
  6. LeakyClass* myLeakyInstance = new LeakyClass();  
  7. delete myLeakyInstance;  
  8.  
  9. mMyLeakyString = [[NSString alloc] initWithUTF8String:”I’m a leaky string.”];  
  10.  
  11. [self doSomethingNow];  
  12. }  
  13.  
  14. - (void) doSomethingNow  
  15. {  
  16. mMyLeakyString = [[NSString alloc] initWithUTF8String:  
  17. “Look, another alloc, but no release for first one!”];  
  18. }  
  19.  
  20. // Leaky excerpts – see GitHub for complete source  
  21.  
  22. LeakyClass::LeakyClass()  
  23. {  
  24. mLeakedObject = new LeakedObject();  
  25. }  
  26.  
  27. LeakyClass::~LeakyClass()  
  28. {  

我會(huì)先在 Debug 模式編譯InstrumentsTest,并在 iPhone 上運(yùn)行。完成這步,我會(huì)啟動(dòng) Instruments。

詳解iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引

當(dāng)你啟動(dòng) Instruments,你可以從一堆 Instruments 工具里選擇你需要的。在左手邊選擇 iPhone,在右手邊的圖標(biāo)里雙擊“Leaks”工具:

詳解iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引

之后你會(huì)看到下邊的窗口:

詳解iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引

請(qǐng)確保 iPhone 已經(jīng)連接到了你的電腦,在這個(gè)窗口的左上角,你會(huì)看到一個(gè)下拉菜 單,寫(xiě)著“Launch Executable”。單擊它,并確保選中的是你 iPhone(而不是你的電腦)作為活動(dòng)設(shè)備。然后移動(dòng)到“Launch Executable”,你可以看到一個(gè)包含了所有已安裝 iPhone 程序的列表。找到你希望運(yùn)用“Leaks”工具的程序(本例中是 InstrumentsTest)并單擊它。

詳解iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引

你已經(jīng)準(zhǔn)備好了。單擊紅色的“Record”按鈕,它會(huì)啟動(dòng)程序并開(kāi)始記錄程序里的每個(gè)內(nèi)存分配操作。它會(huì)每10秒自動(dòng)地檢測(cè)內(nèi)存泄露。

詳解iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引

你 可以改變多少時(shí)間自動(dòng)檢測(cè)一次,你也可以手動(dòng)進(jìn)行檢測(cè)(檢測(cè)內(nèi)存泄露的時(shí)候程序會(huì)停頓大約3-5秒鐘,如果你想邊進(jìn)行測(cè)試邊進(jìn)行內(nèi)存檢測(cè)的話,這種停頓將 會(huì)干擾到你)。我一般是設(shè)置成手動(dòng)控制,在我需要的時(shí)候才單擊“Check for leaks”按鈕(例如:在loading新的游戲模式之后檢測(cè)一下,在退出游戲返回 MM 的時(shí)候檢測(cè)一下)。單擊“Leaks”,并使用右上角的 View->Detail 按鈕來(lái)設(shè)置和查看選項(xiàng)值,在這個(gè)例子里,我將其設(shè)置成 auto。

詳解iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引

程序在運(yùn)行一段時(shí)間之后,自動(dòng)內(nèi)存檢測(cè)將會(huì)發(fā)現(xiàn)兩處內(nèi)存泄露。太棒了!現(xiàn)在該干什么呢?

詳解iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引

Extended Detail 視圖

Instruments 非常懶,它不會(huì)明顯地指出下一步該干什么。你需要注意的是窗口底部的那一排按鈕??匆?jiàn)兩個(gè)矩形組成的那個(gè)按鈕了嗎?講你的鼠標(biāo)停留在上邊,它會(huì)提示“Extended Detail View”,如圖:

詳解iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引

單擊這個(gè)按鈕,右邊將會(huì)彈出一個(gè)窗口,里邊提供了各種關(guān)于內(nèi)存泄露的詳細(xì)信息。單擊一個(gè)內(nèi)存泄露,Extended Detail 視圖將會(huì)顯示泄露的內(nèi)存代碼的完整調(diào)用堆棧。在我們上邊的例子中,單擊第一個(gè)內(nèi)存泄露提示,它發(fā)生在 [NSString initWithUTF8String]。如果你選中調(diào)用堆棧里的高亮步驟,你會(huì)看到程序最后一次調(diào)用是

  1. [InstrumentsTestViewController viewDidLoad] 

雙擊 Extend Detail 視圖中的某行,它會(huì)打開(kāi) XCode 窗口并顯示出問(wèn)題的代碼,這是非常棒的功能。

詳解iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引

在本例中,第一次 NSString 分配的時(shí)候出現(xiàn)了泄露,你需要做一些處理。這是個(gè)非常簡(jiǎn)單的例子,但找到為什么會(huì)發(fā)生泄露則要麻煩些。讓我們仔細(xì)看一下例子。在 viewDidLoad 當(dāng)中,我們?yōu)樽址峙涞搅藘?nèi)存,如下所示:

  1. mMyLeakyString = [[NSString alloc] initWithUTF8String:”I’m a leaky string.”]; 

在 dealloc 當(dāng)中我們用如下方式來(lái)釋放

  1. [mMyLeakyString release]; 

你的直覺(jué)可能是這樣不會(huì)發(fā)生泄露,但搜索代碼中所有用到了 mMyLeakyString 的地方,在 doSomethingNow 中,它是這樣用的:

  1. mMyLeakyString = [[NSString alloc] initWithUTF8String:  
  2. “Look, another alloc, but no release for first one!”]; 

注意,我們聲明了一個(gè)新的字符串,并且將 mMyLeakyString 指向了它。這里的問(wèn)題是我們沒(méi)有在更改 mMyLeakyString 的指向前釋放它原 來(lái)指向的內(nèi)存。所以原始的字符串依然在堆中,并且我們沒(méi)有辦法釋放這部分內(nèi)存。dealloc 里的 release 操作實(shí)際釋放的是我們?cè)?doSomethingNow 中聲明的字符串所占內(nèi)存,因?yàn)檫@才是指針?biāo)浮?/p>

為了修復(fù)這個(gè)問(wèn)題,我們可以把 doSomethingNow 改成下邊的代碼:

  1. - (void) doSomethingNow  
  2. {  
  3. [mMyLeakyString release];  
  4. mMyLeakyString = [[NSString alloc] initWithUTF8String:  
  5. “Look, another alloc, but released first one!”];  

這段代碼做的是在我們指定 mMyLeakyString 到新的字符串前釋放第一個(gè)字符串所占內(nèi)存。重新編譯運(yùn)行程序,你會(huì)看到只有一個(gè)內(nèi)存泄露。當(dāng)然,在項(xiàng)目中可能有更好的方式來(lái)處理 NSString,但如果你這樣處理的話可以修復(fù)這個(gè)泄露問(wèn)題。

讓我們看看第二個(gè)泄露問(wèn)題。單擊泄露提示看什么導(dǎo)致了內(nèi)存泄露。發(fā)現(xiàn)這個(gè)泄露來(lái)自于 LeakyClass::LeakyClass() 構(gòu)造函數(shù),如圖:

詳解iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引

在調(diào)用堆棧中雙擊它,出問(wèn)題的代碼將會(huì)再次出現(xiàn)在 XCode 中,如圖:

詳解iPhone應(yīng)用中內(nèi)存泄露使用Leaks工具指引

我們看到在構(gòu)造函數(shù)里聲明了一個(gè)新的 LeakedObject 對(duì)象,但是析構(gòu)函數(shù)沒(méi)有刪除,這樣不好。對(duì)于每一個(gè) new 操作,都需要有與之對(duì)應(yīng)的 delete 操作。所以我們把析構(gòu)函數(shù)改變成下邊的樣子:

  1. LeakyClass::~LeakyClass()  
  2. {  
  3. if (mLeakedObject != NULL)  
  4. {  
  5. delete mLeakedObject;  
  6. mLeakedObject = NULL;  
  7. }  

重新編譯運(yùn)行,沒(méi)有內(nèi)存泄露了!

我選擇這兩個(gè)例子,雖然非常簡(jiǎn)單,但他們展示了 Instruments 可以用來(lái)追蹤 Object-C 和 C++ 中的內(nèi)存泄露。

修復(fù)你的內(nèi)存泄露問(wèn)題吧,記住,沒(méi)有內(nèi)存泄露的程序才是一個(gè)好程序。

小結(jié):iPhone應(yīng)用內(nèi)存泄露使用Leaks工具指引的內(nèi)容介紹完了,希望通過(guò)本文的學(xué)習(xí)能對(duì)你有所幫助!

責(zé)任編輯:zhaolei 來(lái)源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-07-21 17:45:44

iPhone 內(nèi)存泄露 Leaks

2010-11-05 13:02:58

內(nèi)存iPhone

2011-08-17 15:10:21

iPhone開(kāi)發(fā)Web視圖

2011-08-10 17:37:00

iPhoneASIHTTPRequ

2011-08-02 17:27:06

iPhone應(yīng)用 剪切技巧

2011-06-03 10:19:59

iphone Objective-

2011-07-06 17:48:30

iPhone Xcode 模擬器

2011-08-12 14:33:06

iPhone緩存文件

2011-08-15 11:37:20

iPhone開(kāi)發(fā)Mask

2011-09-15 15:58:37

iPhone應(yīng)用Quick Snap拍攝工具

2011-08-19 14:27:29

iPhone開(kāi)發(fā)

2011-08-09 14:08:51

iPhoneHTTP請(qǐng)求協(xié)議

2011-08-03 17:18:58

iPhone UILabel UISlider

2011-08-18 15:56:08

iPhone開(kāi)發(fā)內(nèi)存

2011-07-26 16:33:56

iPhone Delegate

2011-07-27 10:16:41

iPhone SQLite 數(shù)據(jù)庫(kù)

2011-08-11 13:35:28

iPhoneASIHTTPRequHTTP

2016-09-12 16:01:28

Android內(nèi)存泄露內(nèi)存管理

2012-03-02 14:20:46

JavaJVM

2011-08-08 13:50:29

iPhone開(kāi)發(fā) NSOperatio 多線程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)