EXC_BAD_ACCESS iOS內存錯誤

由於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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章