使用Xcode和Instruments調試解決iOS內存泄露

雖然iOS 5.0版本之后加入了ARC機制,但由于相互引用關系比較復雜時,內存泄露還是可能存在。所以了解原理很重要。

這里講述在沒有ARC的情況下,如何使用Instruments來查找程序中的內存泄露,以及NSZombieEnabled設置的使用。

本文假設你已經比較熟悉Obj-C的內存管理機制。

實驗的開發環境:XCode 4.5.2

1、運行Demo。

先下載一個實現準備好的內存泄露的Demo吧:

leak app

下載下來,打開運行,程序是一個壽司的列表,列出各種壽司卷。試著選擇里面的幾行,應該是選第二行的時候就崩潰了。崩潰截圖:

在崩潰的地方斷住了,知道crash的地方了,但是不知道具體crash的原因。

2、設置NSZombieEnabled

這是一個 “EXC_BAD_ACCESS”錯誤。我們打開XCode的選項:“NSZombieEnabled” 。在crash時可能會給你更多的一些提示信息。

設置步驟:1

2:勾上紅色框里的

運行,按剛才的操作選中其中的cell。再次crash,這次在output窗口會看到多了一項錯誤信息:

2012-11-28 13:22:08.911 PropMemFun[2132:11303] *** -[CFString respondsToSelector:]: message sent to deallocated instance 0x713ebc0

大概意思是:向已釋放的內存發送消息。也就是說使用了已釋放的內存,在C語言相當于使用了“野指針”

看了下crash的這個語句,sushiString應該是沒問題的,它是從stringWithFormat初始化出來的。那就是_lastSushiSelected的問題。

_lastSushiSelected指向了sushiString,sushiString是一個autorelease變量。 在第二次點擊時,使用的是sushiString已經被釋放,所以crash了。那為_lastSushiSelected保留一下,就可以用了。代碼修改如下:

?

<span style="font-size:14px;"> ? ?_lastSushiSelected = [sushiString retain];?

</span>?

?

運行,這時候不崩潰。

3、分析內存泄露(shift+command+b)

app不crash了,那看看有沒有內存泄露。用XCode的Analyze就能分析到哪里有內存泄露

分析之后可以看到:

這里提示alertView沒被釋放,有內存泄露,那我們釋放

? ? [alertView release];

再分析,這個問題解決了。

4、使用Instruments的leaks工具

分析內存泄露不能把所有的內存泄露查出來,有的內存泄露是在運行時,用戶操作時才產生的。那就需要用到Instruments了。

?

按上面操作,build成功后跳出Instruments工具,選擇Leaks選項,這時候壽司程序也運行起來了,選中list中的項,拖動等操作后,工具顯示效果如下:

大家可能都能猜到,紅色的柱子表示內存泄露了。怎么通過這個工具看到在哪泄露了呢?

先在工具欄按下紅色的圓形按鈕,把工具監視內存的活動停下來。選擇Leak,然后點中間十字交叉那,選擇Call Tree

這時候左下角的Call Tree的可選項可以選了。選中Invert Call Tree 和Hide System Libraries,顯示如下:

這時候內存泄露的具體代碼找到了,在右邊的紅色框框里指定了哪個方法出現了內存泄露。

你只要在這些方法上雙擊,就會跳轉到具體的代碼,哈哈,是不是很方便。

這里應該是提示100%內存會泄露。

6、解決內存泄露問題

問題找到了,那就解決吧。

關于:tableView:didSelectRowAtIndexPath ,分析下它的內存過程:

sushiString變量通過autorelease創建,它的引用計數是1. ??

這行代碼使得引用計數增加到2, _lastSushiSelected = [sushiString retain];

這個方法結束時,sushiString的autorelease生效了,這個變量的引用計數減少為1

當再次執行tableView:didSelectRowAtIndexPath這個方法時,_lastSushiSelected被賦值了新指針,老的_lastSushiSelected的引用計數還是1,沒有被釋放,產生了內存泄露。

怎么解決呢?

?

在_lastSushiSelected = [sushiString retain];之前把原來的release就ok了:

?

[_lastSushiSelected release]; ??

? ? _lastSushiSelected = [sushiString retain]; ??

?

?

關于:tableView:cellForRowAtIndexPath

這個比較明顯,sushiString被alloc和init之后就沒有釋放,可以用stringWithFormat來調用autorelease,代碼如下:

?

NSString *sushiString = [NSString stringWithFormat:@"%d: %@", indexPath.row, sushiName]; ?

好了,泄露都fix了,再用工具分析看看,這時候你再點,再拖,再怎么操作,都沒有內存泄露了。表明內存泄露被堵住了。

?

?

?

轉載自: ?http://www.cocoachina.com/newbie/basic/2012/1204/5242.html

轉載于:https://www.cnblogs.com/Xer-Lee/archive/2013/06/06/3120538.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/376625.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/376625.shtml
英文地址,請注明出處:http://en.pswp.cn/news/376625.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

0755、0644、0600 linux文件權限

0755->即用戶具有讀/寫/執行權限&#xff0c;組用戶和其它用戶具有讀寫權限&#xff1b; 0644->即用戶具有讀寫權限&#xff0c;組用戶和其它用戶具有只讀權限&#xff1b; 0600->僅擁有者具有文件的讀取和寫入權限

[Android] (在ScrollView里嵌套view)重疊view里面的onTouchEvent的調用方法

在我前面的自定義裁剪窗口的代碼中&#xff0c;我把裁剪的view放在了大的scrollview里&#xff0c;這樣就出現了程序只能觸發scrollview&#xff0c;無法操作我的裁剪窗口。所以我加了那篇博客下面最后兩段代碼。其實我遇到這個問題的時候是在一個scrollview里添加了一個Editte…

帶點擊事件的Spinner

最近有一個蛋疼的需求&#xff0c;在下拉框中&#xff0c;如果只有一個值&#xff0c;默認顯示出來&#xff0c;有兩個或者沒有顯示請選擇&#xff0c;沒有點擊不彈框&#xff0c;但是要清空&#xff0c;兩個點擊開要移掉請選擇字樣的項 本來以為很簡單&#xff0c;后來發現沒有…

linux進程間通信快速入門【二】:共享內存編程(mmap、XSI、POSIX)

文章目錄mmap內存共享映射XSI共享內存POSIX共享內存參考使用文件或管道進行進程間通信會有很多局限性&#xff0c;比如效率問題以及數據處理使用文件描述符而不如內存地址訪問方便&#xff0c;于是多個進程以共享內存的方式進行通信就成了很自然要實現的IPC方案。LInux給我們提…

ROBOTS.TXT屏蔽筆記、代碼、示例大全

自己網站的ROBOTS.TXT屏蔽的記錄&#xff0c;以及一些代碼和示例&#xff1a; 屏蔽后臺目錄&#xff0c;為了安全&#xff0c;做雙層管理后臺目錄/a/xxxx/&#xff0c;蜘蛛屏蔽/a/&#xff0c;既不透露后臺路徑&#xff0c;也屏蔽蜘蛛爬后臺目錄 緩存&#xff0c;阻止蜘蛛爬靜態…

五大主流瀏覽器 HTML5 和 CSS3 兼容性比較

轉眼又已過去了一年&#xff0c;在這一年里&#xff0c;Firefox 和 Chrome 在拼升級&#xff0c;版本號不斷飆升&#xff1b;IE10 隨著 Windows 8 在去年10月底正式發布&#xff0c;在 JavaScript 性能和對 HTML5 和 CSS3 的支持方面讓人眼前一亮。這篇文章給大家帶來《五大主流…

Ubuntu下將Sublime Text設置為默認編輯器

轉自將Sublime Text 2設置為默認編輯器 修改defaults.list 編輯/etc/gnome/default.list文件&#xff0c;將其中的所有gedit.desktop替換為sublime_text.desktop。 sublime_text.desktop在/opt/sublime_text目錄下&#xff0c;使用ls -al *sublime*命令查看具體文件名。 轉載于…

python獲取最近N天工作日列表、節假日列表

# 獲取最近兩周工作日列表、節假日列表 import datetime import chinese_calendar import time import pandas as pd# 將時間戳轉換成格式化日期 def timestamp_to_str(timestampNone, format%Y-%m-%d %H:%M:%S):if timestamp:time_tuple time.localtime(timestamp) # 把時間…

保存頁面的瀏覽記錄

我的設計思想是將用戶的瀏覽記錄保存到cookie里面&#xff0c;然后根據情況處理。cookie里面的數據格式是json格式&#xff0c;方便根據自己的需要添加或者修改屬性。引用了3個js文件,下載地址如下。 https://github.com/carhartl/jquery-cookie/blob/master/jquery.cookie.js …

開竅小老虎,一步一個腳印之 初識匯編(一)

最近一直浸淫在計算機編程中無法自拔。哲學 認識論中講過。人類的求知的過程是由兩次飛躍。第一是從感性認識到理性認識&#xff1b;第二是從理性認識到實踐。這段話對有些人是適用的。我就是其中的一名。在知乎上求助問題“學計算機要懂匯編嗎&#xff1f;”&#xff0c;地下有…

python腳本 請求數量達到上限,http請求重試

由于在內網發送http請求同一個token會限制次數&#xff0c;所以很容易達到網關流量上限。 業務中使用了多線程并發&#xff0c;一個線程發起一次http請求&#xff0c;得到正確結果后返回。這里采用的策略是&#xff0c;如果解析出來達到流量上限&#xff0c;那么該線程休眠一段…

shell 字符串操作

string"abcABC123ABCabc" 字符串長度: echo ${#string} #15 echo expr length $string #15 索引 用法&#xff1a;expr index $string $substring expr index $string "ABC" #4 提取子串 用法&#xff1a;${string:position} echo ${string:3} #A…

Linux 之目錄 -鳥哥的Linux私房菜

因為利用 Linux 來開發產品或 distributions 的社群/公司與個人實在太多了, 如果每個人都用自己的想 法來配置檔案放置的目錄,那么將可能造成很多管理上的困擾。 你能想象,你進入一個企業之后,所 接觸到的 Linux 目錄配置方法竟然跟你以前學的完全不同嗎? 很難想象吧~所以,后來…

python腳本:向表中插入新數據,刪除表中最舊的數據

一張表存儲歷史數據&#xff0c;最多存儲HISTORY_TABLE_MAX_ROWS條數據&#xff0c;當表中數據未達到HISTORY_TABLE_MAX_ROWS&#xff0c;直接插入&#xff1b;如果達到的話需要保證插入新數據的時候將最舊的數據刪除 這里使用先update最新數據&#xff0c;然后再重新update全表…

精通 VC++ 實效編程280例 - 02 菜單和光標

菜單和關閉時重要的 Windows 資源之一。SDK 中&#xff0c;用 HCURSOR 和 HMENU 分別表示菜單和光標的句柄。MFC 中&#xff0c;CMenu 類封裝了菜單的功能。 23 動態添加和刪除菜單項 添加菜單項可以調用 CMenu::AppendMenu 或 CMenu::InserMenu 函數&#xff0c;刪除菜單項可以…

POJ 1860: Currency Exchange 【SPFA】

套匯問題&#xff0c;從源點做SPFA&#xff0c;如果有一個點入隊次數大于v次&#xff08;v表示點的個數&#xff09;則圖中存在負權回路&#xff0c;能夠套匯&#xff0c;如果不存在負權回路&#xff0c;則判斷下源點到自身的最長路是否大于自身&#xff0c;使用SPFA時松弛操作…

python腳本:判斷字符是否為中文

# 判斷字符是否為中文 def is_chinese(ch):if u\u4e00 < ch < u\u9fff:return Trueelse:return False

Android 廣播 Broadcast學習

Android Broadcast 廣播 進程內本地廣播 如果你是在你的應用之內使用廣播&#xff0c;即不需要跨進程&#xff0c;考慮使用LocalBroadcastManager &#xff0c;這樣更有效率&#xff08;因為不需要跨進程通信&#xff09;&#xff0c;并且你不用考慮一些其他應用可以發送或接收…

python:將時間戳轉換成格式化日期

import time # 將時間戳轉換成格式化日期 def timestamp_to_str(timestampNone, format%Y-%m-%d %H:%M:%S):if timestamp:time_tuple time.localtime(timestamp) # 把時間戳轉換成時間元祖result time.strftime(format, time_tuple) # 把時間元祖轉換成格式化好的時間retur…

WebApp 里Meta標簽大全

1.先說說mate標簽里的viewport&#xff1a; viewport即可視區域&#xff0c;對于桌面瀏覽器而言&#xff0c;viewport指的就是除去所有工具欄、狀態欄、滾動條等等之后用于看網頁的區域。對于傳統WEB頁面來說&#xff0c;980的寬度在iphone上顯示是很正常的&#xff0c;也是滿屏…