EXC_BAD_ACCESS的本質詳解以及殭屍模式調試原理

原文:What Is EXC_BAD_ACCESS and How to Debug It debug

有時候,你會遇到由EXC_BAD_ACCESS形成的崩潰。 這篇文章會告訴你什麼是EXC_BAD_ACCESS,以及它產生的緣由。我還會提供一些EXC_BAD_ACCESS錯誤的解決方案。 指針

1. 什麼是 EXC_BAD_ACCESS? 調試

一旦你理解EXC_BAD_ACCESS的本質,你就會更好地理解這個模糊的名詞。這裏有一個極爲簡單的解釋,也有一個技術層面的解釋。咱們首先從簡單的解釋開始提及。 code

2.簡單的解釋 對象

無論何時當你遇到EXC_BAD_ACCESS這個錯誤,那就意味着你向一個已經釋放的對象發送消息。這是最多見的狀況,但也有例外,咱們將在稍後討論。 內存

3. EXC_BAD_ACCESS的本質 ci

技術層面的解釋有些複雜。在C和Objective-C中,你一直在處理指針。指針無非是存儲另外一個變量的內存地址的變量。當您向一個對象發送消息時,指向該對象的指針將會被引用。這意味着,你獲取了指針所指的內存地址,並訪問該存儲區域的值。 unicode

當該存儲器區域再也不映射到您的應用時,或者換句話說,該內存區域在你認爲使用的時候卻沒有使用,該內存區域是沒法訪問的。 這時內核會拋出一個異常( EXC ),代表你的應用程序不能訪問該存儲器區域(BAD ACCESS) 。 開發

總之,當你碰到EXC_BAD_ACCESS ,這意味着你試圖發送消息到的內存塊,但內存塊沒法執行該消息。可是,在某些狀況下, EXC_BAD_ACCESS是由被損壞的指針引發的。每當你的應用程序嘗試引用損壞的指針,一個異常就會被內核拋出。 get

4.調試EXC_BAD_ACCESS

調試EXC_BAD_ACCESS可能會很是棘手和使人沮喪。然而,如今EXC_BAD_ACCESS再也不是一個謎,它沒有想象中的那麼可怕。

你須要知道的第一件事是您的應用程序並不必定是在崩潰的那一刻,沒法訪問內存區域。這就是常使調試EXC_BAD_ACCESS變得困難的緣由。

一樣受損指針也是如此。當你的指針被損壞時,您的應用程序不會崩潰。同時,若是您在應用程序中來回傳遞一個受損的指針也不會崩潰。當應用程序試圖引用受損指針的時候,就會發生奔潰。

5.殭屍調試模式

殭屍調試模式在過去幾年中獲得了普及,事實上它們已經出如今Xcode上超過十年。殭屍聽起來有點戲劇性,但它其實是爲幫助咱們調試EXC_BAD_ACCESS功能而取得一個偉大的名字。讓我來解釋它是如何工做的。

在Xcode中,您能夠啓用殭屍對象,這意味着被釋放的對象將會以殭屍的形式被保留。換言之,保留釋放的對象就是爲了調試。這裏沒有涉及任何魔法。若是您向殭屍對象發送消息,你的應用程序將會因爲EXC_BAD_ACCESS而崩潰。

這有什麼好處嗎?讓EXC_BAD_ACCESS難以調試的緣由是,你不知道你的應用程序試圖訪問哪一個對象。殭屍對象在許多狀況下解決這個問題。經過保留已釋放的對象,Xcode能夠告訴你你試圖訪問哪一個對象,這使的查找問題緣由容易得多。

在Xcode中啓用殭屍對象是很容易的。注意,這可能會因的Xcode的版本而不一樣的。如下方法適用於Xcode的6和7,單擊左上角的Edit Scheme,並選中Edit Scheme。

在左側選中Run ,在上方打開 Diagnostics選項。要啓用殭屍對象,勾選 Enable Zombie Objects選框。


若是你如今遇到EXC_BAD_ACCESS ,在Xcode的控制檯輸出,告訴你該從哪裏查找問題。看看下面的例子輸出。

2015-08-12 06:31:55.501 Debug[2371:1379247] -[ChildViewController respondsToSelector:] message sent 
to deallocated instance 0x17579780

在上面的例子中, Xcode告訴咱們, respondsToSelector的消息:被髮送到一個殭屍對象。然而,殭屍對象再也不是ChildViewController類的一個實例。之前分配給ChildViewController實例的內存區域再也不映射到您的應用程序。這爲你瞭解問題產生的根本緣由提供一個不錯的建議。

不幸的是,殭屍對象將沒法保存您的一天每次崩潰的EXC_BAD_ACCESS的記錄。既然殭屍對象沒有這些方法,那麼你能夠採起其餘的方法進行一些適當的分析。

6.分析

若是殭屍對象不能解決你的問題,那麼問題的根源可能就不那麼簡單了。在這種狀況下,您須要仔細看看在應用程序崩潰時執行的代碼。這多是繁瑣和耗時的。

爲了幫助你發現你的代碼的問題,你可使用Xcode來分析你的代碼,幫助你找到出現問題的地方。注意,Xcode分析項目,它會指出每個潛在的可能出現的問題的地方。

使用Xcode來分析你的項目,從Xcode的 Product菜單選擇 Analyze或按 Shift-Command-B.Xcode的將須要片刻的時間,可是當它完成的時候你會在左邊的 Issue Navigator看到問題列表。由Analyze發現的問題用藍色高亮顯示。


當你點擊一個問題,Xcode的會指向問題代碼塊,這些正是你要的注意的地方。注意,Xcode僅僅是建議。在某些狀況下,這是可能的,問題是不相關的,不固定。


若是你找不到形成EXC_BAD_ACCESS的錯誤,那就須要你仔細審視Xcode項目,分析其中發現的每個問題。

7.結論

EXC_BAD_ACCESS是開發者面臨的一個共同的問題,它是手動內存管理固有的問題。雖然推行ARC內存管理方式 (自動引用計數)使得EXC_BAD_ACCESS沒那麼頻繁,但他們並無真正的消失。

相關文章
相關標籤/搜索