IOS開發(46)之設定 NSZombieEnabled 定位 EXC_BAD_ACCESS 錯誤

來源:互聯網
上載者:User

我們做 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 子類中這樣的代碼:

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”

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 後的效果是一樣的。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.