iOS開發(fā),最郁悶的莫過(guò)于程序毫無(wú)征兆地就崩潰了,用bt命令打出調(diào)用棧,給出的是一堆系統(tǒng)EXC_BAD_ACCESS的信息,根本沒(méi)辦法定位問(wèn)題出現(xiàn)在哪里。 首先說(shuō)一下 EXC_BAD_ACCESS 這個(gè)錯(cuò)誤,可以這么說(shuō),90%的錯(cuò)誤來(lái)源在于對(duì)一個(gè)已經(jīng)釋放的對(duì)象進(jìn)行release操作。舉一個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明吧,首先看一段Java代碼:
(通過(guò)Product->Scheme->Edit Scheme進(jìn)入下面編輯頁(yè)面,選中Arguments tab,增加標(biāo)計(jì)位NSZombieEnabled設(shè)為YES)

這樣,但崩潰出現(xiàn),系統(tǒng)會(huì)出現(xiàn)以下提示信息:
2013-06-23 00:45:20.479 *** -[__NSArrayM addObject:]: message sent to deallocated instance 0x7179910
可見崩潰原因是內(nèi)存地址0x7179910被重復(fù)釋放了。
Objective-C 這段代碼有三個(gè)致命問(wèn)題:1、內(nèi)存泄露;2、錯(cuò)誤釋放;3、造成 EXC_BAD_ACCESS 錯(cuò)誤。
如果崩潰是發(fā)生在當(dāng)前調(diào)用棧,通過(guò)上面的做法,系統(tǒng)就會(huì)把崩潰原因定位到具體代碼中。但是,如果崩潰不在當(dāng)前調(diào)用棧,系統(tǒng)就僅僅只能把崩潰地址告訴我們,而沒(méi)辦法定位到具體代碼,這樣我們也沒(méi)法去修改錯(cuò)誤。這時(shí)就可以修改scheme,讓xcode記錄每個(gè)地址alloc的歷史,這樣我們就可以用命令把這個(gè)地址還原出來(lái)。如圖:(跟設(shè)置NSZombieEnabled一樣,添加MallocStackLoggingNoCompact,并且設(shè)置為YES)

這樣,當(dāng)出現(xiàn)崩潰原因是message sent to deallocated instance 0x7179910,我們可以使用以下命令,把內(nèi)存地址還原:
info malloc-history 0x7179910
如圖,這個(gè)命令能具體把這個(gè)地址在哪一行代碼生成還原出來(lái)。

(需要注意的是,因?yàn)檫@個(gè)命令只支持gdb,所以必須把控制臺(tái)的輸出改成gdb,并且有點(diǎn)遺憾的是,只支持模擬器,不支持真機(jī)調(diào)試)

(同樣是通過(guò)Product->Scheme->Edit Scheme進(jìn)入上面編輯頁(yè)面,選中Info tab)
這樣,好好檢查一下那一行的代碼,應(yīng)該就很容易找出問(wèn)題所在了。
新聞熱點(diǎn)
疑難解答
圖片精選