iOS開發過程當中,普通的bug一般較容易定位問題所在,可是,EXD_BAD_ACCEEE問題卻比較不易查找問題。本文記錄下解決EXD_BAD_ACCEEE問題的過程。首先說一下 EXC_BAD_ACCESS 這個錯誤,能夠這麼說,90%的錯誤來源在於對一個已經釋放的對象進行release操做。shell
1. 重寫object的respondsToSelector方法,現實出現EXEC_BAD_ACCESS前訪問的最後一個objectiphone
有時程序崩潰根本不知錯誤發生在什麼地方。好比程序出現EXEC_BAD_ACCESS的時候,雖然大部分狀況使用設定 NSZombieEnabled環境變量能夠幫助你找到問題的所在,但少數狀況下,即便設定了NSZombieEnabled環境變量,仍是不知道程序崩 潰在什麼地方。那麼就須要使用下列代碼進行幫助了:spa
#ifdef _FOR_DEBUG_ -(BOOL) respondsToSelector:(SEL)aSelector { printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]); return [super respondsToSelector:aSelector]; } #endif
你須要在每一個object的.m或者.mm文件中加入上面代碼,而且在 other c flags中加入-D _FOR_DEBUG_(記住請只在Debug Configuration下加入此標記)。這樣當你程序崩潰時,Xcode的console上就會準確地記錄了最後運行的object的方法。調試
2. 經過NSZombieEnabledcode
相信不少人都知道經過NSZombies來幫助調試出現EXC_BAD_ACCESS的狀況,但有時仍是找不到須要的信息,那麼應該怎麼辦呢?orm
下面經過一個例子來講明.下面是hello world的代碼:htm
NSString* hello = [NSString stringWithFormat:@"Hello world"]; NSLog(@"What you say is %@",hello); [hello release];
運行後出現EXC_BAD_ACCESS錯誤.但沒有其餘任何提示,這時 候經過右擊executables下的應用程序名,選擇get info後,在arguments下輸入環境變量(NSZombieEnabled,MallocStackLogging)對象
再次運行後程序crash,如圖:blog
此次能夠看到問題是」message sent to dealloced object」了,但具體是哪一個語句引發的還並不知道,因而須要在gdb上輸入如下語句:圖片
shell malloc_history pid address
那麼pid和address是什麼呢?再看下crash的圖片結合一下我如下使用的命令,你應該很快就能夠斷定pid和address是從哪裏來的了,個人命令是:
shell malloc_history 596 0×5f3ef80
再次運行,程序crash時會出現大量的stack trace信息,以下圖是與本程序相關的:
根據這些信息你們就能夠找到問題出如今[BadAccessViewController viewDidLoad] 中與 +[NSString stringWithFormat:] 有關的地方.
最後你們記得把環境變量NSZombieEnabled,MallocStackLogging刪除或設置爲NO,由於它們會使得內存不會被真實釋放.
三、設置全局斷點快速定位問題代碼所在行
XCode調試技巧–設置全局斷點快速定位問題代碼所在行