- 簡單的理解:當遇到了EXC_BAD_ACCESS異常想鹰,意味著訪問了一個已經被釋放的內存區(qū)域黔牵。
- 指針層面理解:從C斗蒋、OC語言來解釋坚洽,我們平時所操作的對象其實是一個指針戈稿,指針是指向另一塊存儲區(qū)域的變量。當向一個對象發(fā)送消息讶舰,指向這個對象的指針需要被使用鞍盗,也就是你獲得了指針指向的內存地址并且可以訪問該內存塊的值。當系統(tǒng)不再為你映射該內存塊時跳昼,換句話說般甲,該內存塊已經不能夠被你所使用,則不可以再次訪問該內存塊鹅颊。 如果再次訪問這塊內存欣除,發(fā)生這種情況時,內核會發(fā)送一個異常(EXC)挪略,表明您的應用程序無法訪問該內存塊(BAD ACCESS)。
總之滔岳,當遇到了EXC_BAD_ACCESS異常杠娱,意味你嘗試向一個塊已經不能執(zhí)行這個消息的內存塊發(fā)送消息。
在某些情況下谱煤,訪問野指針也會導致EXC_BAD_ACCESS摊求。當應用程序嘗試去使用一個野指針的時候,EXC_BAD_ACCESS就會被內核拋出刘离。
調試EXC_BAD_ACCESS
因為當內存塊不能被應用程序所使用的時候室叉,并不會立即出現(xiàn)crash,所以導致調試EXC_BAD_ACCESS很麻煩硫惕。
對于野指針也是同樣的茧痕,應用程序不會立即崩潰如果存在野指針,只有當應用程序試圖去使用野指針的時候才會崩潰恼除。
僵死對象
僵尸對象聽起來有點奇怪踪旷,但確實是可以用來幫助調試EXC_BAD_ACCESS問題。非常有效豁辉!
Xcode中令野,可以開啟僵尸對象模式。
之所有調試EXC_BAD_ACCESS非常麻煩是因為不知道應用程序要訪問哪個對象徽级。僵尸對象可以解決這個問題气破。
通過讓已經被釋放的對象存活,Xcode可以告訴我們正在訪問哪個被釋放的對象餐抢,進而找到是什么原因引起的现使。
僵尸對象并不能把所有的EXC_BAD_ACCESS找出來低匙。所以必須時需要通過下面的一些方式來解決——比如靜態(tài)分析。
靜態(tài)分析
如果僵尸對象不能解決問題朴下,可以通過靜態(tài)分析的方法來提前發(fā)現(xiàn)努咐。
可以從Xcode中的Product中選則Analyze
,或者直接Shfit+Command+B
殴胧。Xcode將會花點時間把問題的部分有問題的代碼羅列出來渗稍。類似于:
當點擊相關的issue時,就會調到對應的代碼位置团滥。
Xcode只是會做出相應的提示竿屹,在某些情況下,可能某些情況下不用修復灸姊。
- 如果不能準確的定位問題拱燃,那么就只通過靜態(tài)分析一個一個Issue去排查。
總結
EXC_BAD_ACCESS是一個比較常見的但同時也非常麻煩的問題力惯。這是問題是從手動管理內存一直延續(xù)下來的碗誉,雖然現(xiàn)在大部分都是用ARC,但是并不會意味著EXC_BAD_ACCESS就消失父晶。