EXC_BAD_ACCESS的本質詳解以及殭屍模式除錯原理
原文:What Is EXC_BAD_ACCESS and How to Debug It
有時候,你會遇到由EXC_BAD_ACCESS造成的崩潰。 這篇文章會告訴你什麼是EXC_BAD_ACCESS,以及它產生的原因。我還會提供一些EXC_BAD_ACCESS錯誤的解決方案。
1. 什麼是 EXC_BAD_ACCESS?
一旦你理解EXC_BAD_ACCESS的本質,你就會更好地理解這個模糊的名詞。這裡有一個極為簡單的解釋,也有一個技術層面的解釋。我們首先從簡單的解釋開始說起。
2. 簡單的解釋
不管什麼時候當你遇到EXC_BAD_ACCESS這個錯誤,那就意味著你向一個已經釋放的物件傳送訊息。這是最常見的情況,但也有例外,我們將在稍後討論。
3. EXC_BAD_ACCESS的本質
技術層面的解釋有些複雜。在C和Objective-C中,你一直在處理指標。指標無非是儲存另一個變數的記憶體地址的變數。當您向一個物件傳送訊息時,指向該物件的指標將會被引用。這意味著,你獲取了指標所指的記憶體地址,並訪問該儲存區域的值。
當該儲存器區域不再對映到您的應用時,或者換句話說,該記憶體區域在你認為使用的時候卻沒有使用,該記憶體區域是無法訪問的。 這時核心會丟擲一個異常( EXC ),表明你的應用程式不能訪問該儲存器區域(BAD ACCESS) 。
總之,當你碰到EXC_BAD_ACCESS ,這意味著你試圖傳送訊息到的記憶體塊,但記憶體塊無法執行該訊息。但是,在某些情況下, EXC_BAD_ACCESS是由被損壞的指標引起的。每當你的應用程式嘗試引用損壞的指標,一個異常就會被核心丟擲。
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的控制檯輸出,告訴你該從哪裡查詢問題。看看下面的例子輸出。
-[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沒那麼頻繁,但他們並沒有真正的消失。
http://www.cocoachina.com/articles/15324
&n