由於iOS5.0之前沒有自動應用計數機制,也沒有Java那樣的記憶體回收功能。我們都需要自己管理和控制對象的回收,這是一件很麻煩的事情,也是做iOS項目中最容易出現的問題。如果不掌握這些方法,調試這些問題幾乎沒有頭緒。
1、EXC_BAD_ACCESS記憶體錯誤與NSZombieEnabled
EXC_BAD_ACCESS是最常見的錯誤了,這個一般是訪問了釋放了的記憶體位址空間造成的。比如一個對象已經dealloc了,如果你仍向這個對象發送訊息,就會出現這個錯誤。由於出現這個錯誤時,幾乎不顯示什麼有用的資訊,我們根本無法確定程式錯在何處。使用NSZombieEnabled環境變數可以很好的解決這個問題。
開啟你的工程,選擇菜單“Product->Edit Scheme”或快速鍵“Commend+<”
NSZombieEnabled環境變數使釋放的記憶體繼續保持對象的資訊,如果我們向一個已經釋放的對象發送一個訊息,我們會得到一個錯誤訊息,而且程式自動斷點到出錯的位置。如我們向一個已經釋放了的UIButton對象發送description訊息,就會在調試終端上得到以下訊息:
*** -[UIButton description]: message sent to deallocated instance 0x1580f360
此時,程式將自動斷點到”[UIButton description];”這行代碼上。
2、Framework內部對象出現Overrelease與MallocStackLoggingNoCompact
通過NSZombieEnabled環境變數,我們可以很多Bug了。但有時錯誤發生在framework內部,這時斷點的當前棧並不在我們的代碼當中。比如:
xxx: *** -[CALayer release]: message sent to deallocated instance 0xe250df0
這個CALayer並不是我們直接建立,而且release訊息也不發生在我們的代碼中。我們完全不知道這個CALayer是那個View的。所以就沒法明確那個類出現問題。如果知道這個CALayer在什麼地方alloc的就好了,這時我們就需要MallocStackLoggingNoCompact環境變數了。這個環境變數開啟的alloc日誌,它會記錄每個對象alloc時的棧的情況。根據棧的情況我們就可以弄清楚那個類初始化了這個Layer,從而檢查代碼解決問題。設定方法和NSZombieEnabled類似:
當message sent to deallocated instance訊息產生時,在調試終端輸入:
info malloc-history 0xe250df0
就會列印layer alloc時棧的情況,可以看到代碼調用情況,找到我們自己的代碼,檢查代碼並修改吧。
FROM:http://xcodev.com/wordpress/?p=209