寫程序遇到 Bug 並不可怕,大部分的問題,經過簡單的 Log 或者 代碼分析並不難找到緣由所在。可是在 Objective-C 編程中遇到 EXC_BAD_ACCESS 問題的時候,經過簡單常規的手段很難發現問題。這篇文章,給你們介紹一個經常使用的查找 EXC_BAD_ACCESS 問題根源的方法。編程
首先說一下 EXC_BAD_ACCESS 這個錯誤,能夠這麼說,90%的錯誤來源在於對一個已經釋放的對象進行release操做。spa
Objective-C 這段代碼有三個致命問題:一、內存泄露;二、錯誤釋放;三、形成 EXC_BAD_ACCESS 錯誤。對象
1, NSString* s = [[NSString alloc]initWithString:@」This is a test string」]; 建立了一個 NSString Object,隨後的 s = [s substringFromIndex:[s rangeOfString:@"a"].location]; 執行後,致使建立的對象引用消失,直接形成內存泄露。內存
2,錯誤釋放。[s release]; 這個問題,緣由之一是一個邏輯錯誤,覺得 s 仍是咱們最初建立的那個 NSString 對象。第二是由於從 substringFromIndex:(NSUInteger i) 這個方法返回的 NSString 對象,並不須要咱們來釋放,它實際上是一個被 substringFromIndex 方法標記爲 autorelease 的對象。若是咱們強行的釋放了它,那麼會形成 EXC_BAD_ACCESS 問題。string
3, EXC_BAD_ACCESS。因爲 s 指向的 NSString 對象被標記爲 autorelease, 則在 NSAutoreleasePool 中已有記錄。可是因爲咱們在前面錯誤的釋放了該對象,則當 [pool drain] 的時候,NSAutoreleasePool 又一次的對它記錄的 s 對象調用了 release 方法,但這個時候 s 已經被釋放不復存在,則直接致使了 EXC_BAD_ACCESS問題。it
查看更多的Console信息io
工做區->Excuteables->雙擊其分組下的文件->Arguments設置運行參數table
1: 爲工程運行時加入 NSZombieEnabled 環境變量,則在 EXC_BAD_ACCESS 發生時,XCode 的 Console 會打印出問題描述。class
首先雙擊 XCode 工程中,Executables 下的 可執行模組,test
2:加入 MallocStackLogging 來啓用malloc記錄
作以下設置:
Project -> Edit active executable ->Argument
添加以下四個參數
NSDebugEnabled
NSZombieEnabled
MallocStackLogging
MallocStackLoggingNoCompact