EXD_BAD_ACCEEE

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調試技巧–設置全局斷點快速定位問題代碼所在行

注:轉載  stackoverflow

本站公眾號
   歡迎關注本站公眾號,獲取更多信息