在iOS開發(fā)過(guò)程中經(jīng)常會(huì)遇到野指針和僵尸對(duì)象的問(wèn)題积仗,比如訪問(wèn)已經(jīng)釋放對(duì)象的成員變量或者發(fā)消息即會(huì)出現(xiàn)BAD_ACCESS錯(cuò)誤,這類錯(cuò)誤往往在控制臺(tái)中不能很直觀的看到錯(cuò)誤的具體位置和信息寝并,以下幾種方法可以幫助我們快速的定位到錯(cuò)誤的位置并及時(shí)修復(fù):
1.通過(guò) Zombie
如果打開了ARC或垃圾回收模式箫措,在程序中發(fā)消息給已經(jīng)釋放的對(duì)象,將會(huì)引起程序崩潰衬潦。這時(shí)定位崩潰原因?qū)⒎浅@щy斤蔓,因?yàn)槌鰡?wèn)題的對(duì)象已經(jīng)重新分配了《频海【MRC下對(duì)release的對(duì)象再訪問(wèn)弦牡;不支持ARC對(duì)象(CGImageRef)release之后再訪問(wèn)】解決方法:可以通過(guò)啟動(dòng)僵尸對(duì)象(Zombie Objects)來(lái)解決,開啟該選項(xiàng)后漂羊,程序在運(yùn)行時(shí)驾锰,如果訪問(wèn)了已經(jīng)釋放的對(duì)象,則會(huì)給出較準(zhǔn)確的定位信息走越,可以幫助確定問(wèn)題所在椭豫。
功能的原理:在對(duì)象釋放(retainCount 為0)時(shí),使用一個(gè)內(nèi)置的Zombie對(duì)象旨指,替代原對(duì)象赏酥。
第一步:設(shè)置僵尸對(duì)象:
第二步:打開Instrument
第三步:選擇Zombies
第四步:點(diǎn)擊運(yùn)行
然后出現(xiàn)就會(huì)看到如下畫面:
點(diǎn)擊你的模擬器要出現(xiàn)問(wèn)題的地方,重現(xiàn)錯(cuò)誤淤毛,返回到Instruments中今缚,按照下圖操作:
點(diǎn)了箭頭之后,會(huì)有變灰色的行出現(xiàn)低淡,這個(gè)就是出問(wèn)題的地方姓言,雙擊這一行進(jìn)去瞬项,就可以定位到我們出問(wèn)題的地方了:
2.Xcode 7 已經(jīng)集成了BAD_ACCESS捕獲功能:Address Sanitizer。 用法如下:在配置中勾選?Enable Address Sanitizer
AddressSanitizer的原理:當(dāng)程序創(chuàng)建變量分配一段內(nèi)存時(shí)何荚,將此內(nèi)存后面的一段內(nèi)存也凍結(jié)住囱淋,標(biāo)識(shí)為中毒內(nèi)存。AddressSanitizer比Zombie擁有更強(qiáng)大的捕獲能力餐塘,特別是在malloc對(duì)象和內(nèi)存越界方面妥衣。【在Build Settings中的Custom Compiler Flags下為other C Flags添加-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error】
3. 設(shè)置全局?jǐn)帱c(diǎn)快速定位問(wèn)題代碼所在行:
4. 重寫object的respondsToSelector方法戒傻,現(xiàn)實(shí)出現(xiàn)EXEC_BAD_ACCESS前訪問(wèn)的最后一個(gè)object税手。
有時(shí)程序崩潰根本不知錯(cuò)誤發(fā)生在什么地方。 比如程序出現(xiàn)EXEC_BAD_ACCESS的時(shí)候需纳,雖然大部分情況使用設(shè)定 NSZombieEnabled環(huán)境變量可以幫助你找到問(wèn)題的所在芦倒,但少數(shù)情況下,即使設(shè)定了NSZombieEnabled環(huán)境變量不翩,還是不知道程序崩 潰在什么地方兵扬。 那么就需要使用下列代碼進(jìn)行幫助了:
#ifdef _FOR_DEBUG_
-(BOOL) respondsToSelector:(SEL)aSelector {
printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]);
return [super respondsToSelector:aSelector];}
#endif
你需要在每個(gè)object的.m或者.mm文件中加入上面代碼,并且在 other c flags中加入-D FOR_DEBUG(記住請(qǐng)只在Debug Configuration下加入此標(biāo)記)口蝠。 這樣當(dāng)你程序崩潰時(shí)器钟,Xcode的console上就會(huì)準(zhǔn)確地記錄了最后運(yùn)行的object的方法。