设置 NSZombieEnabled 定位 EXC_BAD_ACCESS 错误
生活随笔
收集整理的這篇文章主要介紹了
设置 NSZombieEnabled 定位 EXC_BAD_ACCESS 错误
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
http://unmi.cc/nszombieenabled-locate-exc_bad_access-error, 來自 隔葉黃鶯 Unmi Blog?
我們做 iOS 程序開發時經常用遇到 EXC_BAD_ACCESS 錯誤導致 Crash,出現這種錯誤時一般 Xcode 不會給我們太多的信息來定位錯誤來源,只是在應用 Delegate 上留下像 Thread 1: Program received signal: "EXC_BAD_ACCESS",讓問題無從找起。?
比如你對已釋放的對象發送消息時就會出現,EXC_BAD_ACCESS,再如 release 的對象再 release,release 那些 autorelease 的對象等也會報這樣的錯。默認設置下 Xcode 不會給你定位具體是哪一行代碼,不該去使用已釋放的對象,或者 release 用錯了。?
比如 UIViewController 子類中這樣的代碼:?
Objective-c代碼??static?NSMutableArray?*array;?? ??? -?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ????array?=?[[NSMutableArray?alloc]?initWithCapacity:5];?? ????[array?release];?? }?? ??? -?(void)?viewWillAppear:(BOOL)animated?{????? ????[array?addObject:@"Hello"];?? }??
上面的代碼就會出現 EXC_BAD_ACCESS 錯誤,但我執行時 Xcode 一出錯卻是定位在我在 AppDelegate 的 application:didFinishLaunchingWithOptions: 方法上的某行了,如果代碼量多了,要查找具體問題非常難,只能憑經驗了。?
不過 NSZombieEnabled 環境變量可以幫我們的忙,就是當設置NSZombieEnabled環境變量后,一個對象銷毀時會被轉化為_NSZombie,設置NSZombieEnabled后,當你向一個已經釋放的對象發送消息,這個對象就不會向之前那樣Crash或者產生 一個難以理解的行為,而是放出一個錯誤消息,然后以一種可預測的可以產生debug斷點的方式消失, 因此我們就可以找到具體或者大概是哪 個對象被錯誤的釋放了。?
對 Xcode 設置了 NSZombieEnabled 之后,Xcode 會明確定位在行 [array addObject:@"Hello"],然后控制臺下報的錯誤信息是:?
*** -[__NSArrayM addObject:]: message sent to deallocated instance 0x6557370?
如何設置 NSZombieEnabled 呢,在 Xcode3 和 Xcode4 下設置不一樣,Xcode4 下設置很簡單。?
Xcode3 下 NSZombieEnabled 設置方法如下:?
1.?? 在XCode左邊那個Groups & Files欄中找到Executables,雙擊其中的一項,或者右鍵Get Info;?
2.? 切換到Arguments?
3.? 這里一共有兩個框,在下面那個Variables to be set in the environment:點+號添加一項,Name里填NSZombieEnabled,Value填Yes,要保證前面的鉤是選中的。?
Xcode4 下設置 NSZombieEnabled 的方法:?
你可以點擊 Xcode4 菜單 Product -> Edit Scheme -> Arguments, 然后將點擊”加號”, 將 NSZombieEnabled 參數加到 Environment Variables 窗口中, 后面的數值寫上 ”YES”.?
或者在 Xcode4 菜單 Product -> Edit Scheme -> Diagnostics 設置窗口中直接勾上 Enable Zombie Objects 即可,Xcode 可用 cmd+shift+< 進到這個窗口。?
Xcode4 已經考慮到了現在的要求,所以提供了更便捷的設置的方式,你也可以在這個窗口中設置其他一些參數,你肯定能由此獲得更多的幫助信息。?
另外再說一下,如果沒有為 Xcode 設置 NSZombieEnable,像下面的代碼或許可以正確執行,打印出你所期望的結果 “Hello”.?
Objective-c代碼??static?NSMutableArray?*array;?? ??? -?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ????array?=?[[NSMutableArray?alloc]?initWithCapacity:5];?? ????[array?release];?? ????[array?addObject:@"Hello"];?? ????NSLog(@"%@",?[array?objectAtIndex:0]);?? }??
但是一旦加上了 NSZombieEnable 設置,上面的代碼行? [array addObject:@"Hello"] 也將無法投機取巧了,同樣會得到錯誤提示:?
*** -[__NSArrayM addObject:]: message sent to deallocated instance 0x6557370?
即使該 array 所指向的內存還是原來的數據也不能逃脫掉 NSZombieEnable 的法眼。也就是之所以未設置 NSZombieEnable 時上面代碼能得到正確結果,是因為,雖然 [array release] 是標記為釋放掉該內存塊,但是后面使用 array 時,因為該指針指向的內存數據未被覆蓋,所以未出錯,這和 C++ 的指針 delete 后的效果是一樣的。
我們做 iOS 程序開發時經常用遇到 EXC_BAD_ACCESS 錯誤導致 Crash,出現這種錯誤時一般 Xcode 不會給我們太多的信息來定位錯誤來源,只是在應用 Delegate 上留下像 Thread 1: Program received signal: "EXC_BAD_ACCESS",讓問題無從找起。?
比如你對已釋放的對象發送消息時就會出現,EXC_BAD_ACCESS,再如 release 的對象再 release,release 那些 autorelease 的對象等也會報這樣的錯。默認設置下 Xcode 不會給你定位具體是哪一行代碼,不該去使用已釋放的對象,或者 release 用錯了。?
比如 UIViewController 子類中這樣的代碼:?
Objective-c代碼??
上面的代碼就會出現 EXC_BAD_ACCESS 錯誤,但我執行時 Xcode 一出錯卻是定位在我在 AppDelegate 的 application:didFinishLaunchingWithOptions: 方法上的某行了,如果代碼量多了,要查找具體問題非常難,只能憑經驗了。?
不過 NSZombieEnabled 環境變量可以幫我們的忙,就是當設置NSZombieEnabled環境變量后,一個對象銷毀時會被轉化為_NSZombie,設置NSZombieEnabled后,當你向一個已經釋放的對象發送消息,這個對象就不會向之前那樣Crash或者產生 一個難以理解的行為,而是放出一個錯誤消息,然后以一種可預測的可以產生debug斷點的方式消失, 因此我們就可以找到具體或者大概是哪 個對象被錯誤的釋放了。?
對 Xcode 設置了 NSZombieEnabled 之后,Xcode 會明確定位在行 [array addObject:@"Hello"],然后控制臺下報的錯誤信息是:?
*** -[__NSArrayM addObject:]: message sent to deallocated instance 0x6557370?
如何設置 NSZombieEnabled 呢,在 Xcode3 和 Xcode4 下設置不一樣,Xcode4 下設置很簡單。?
Xcode3 下 NSZombieEnabled 設置方法如下:?
1.?? 在XCode左邊那個Groups & Files欄中找到Executables,雙擊其中的一項,或者右鍵Get Info;?
2.? 切換到Arguments?
3.? 這里一共有兩個框,在下面那個Variables to be set in the environment:點+號添加一項,Name里填NSZombieEnabled,Value填Yes,要保證前面的鉤是選中的。?
Xcode4 下設置 NSZombieEnabled 的方法:?
你可以點擊 Xcode4 菜單 Product -> Edit Scheme -> Arguments, 然后將點擊”加號”, 將 NSZombieEnabled 參數加到 Environment Variables 窗口中, 后面的數值寫上 ”YES”.?
或者在 Xcode4 菜單 Product -> Edit Scheme -> Diagnostics 設置窗口中直接勾上 Enable Zombie Objects 即可,Xcode 可用 cmd+shift+< 進到這個窗口。?
Xcode4 已經考慮到了現在的要求,所以提供了更便捷的設置的方式,你也可以在這個窗口中設置其他一些參數,你肯定能由此獲得更多的幫助信息。?
另外再說一下,如果沒有為 Xcode 設置 NSZombieEnable,像下面的代碼或許可以正確執行,打印出你所期望的結果 “Hello”.?
Objective-c代碼??
但是一旦加上了 NSZombieEnable 設置,上面的代碼行? [array addObject:@"Hello"] 也將無法投機取巧了,同樣會得到錯誤提示:?
*** -[__NSArrayM addObject:]: message sent to deallocated instance 0x6557370?
即使該 array 所指向的內存還是原來的數據也不能逃脫掉 NSZombieEnable 的法眼。也就是之所以未設置 NSZombieEnable 時上面代碼能得到正確結果,是因為,雖然 [array release] 是標記為釋放掉該內存塊,但是后面使用 array 時,因為該指針指向的內存數據未被覆蓋,所以未出錯,這和 C++ 的指針 delete 后的效果是一樣的。
轉載于:https://www.cnblogs.com/DamonTang/archive/2012/08/07/2626602.html
總結
以上是生活随笔為你收集整理的设置 NSZombieEnabled 定位 EXC_BAD_ACCESS 错误的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【网络安全】最全渗透学习攻略
- 下一篇: 《商务与经济统计》要点回顾笔记