轉(zhuǎn)載:http://www.cnblogs.com/ym123/p/4319185.html
相信在使用ARC之前刑然,很多人遇到過EXC_BAD_ACCESS錯誤寥茫,這個錯誤可以理解為訪問了已被釋放的對象魄幕,蘋果稱之為僵尸對象尊浪。
比如在不開啟ARC下堕油,下面這段代碼:
1
2
3NSString* hello = [NSStringstringWithFormat:@"Hello"];
NSLog(@"What you say is %@",hello);
[hello release];
hello對象不是手動分配,而是加入到自動釋放池乐严,由釋放池負(fù)責(zé)釋放瘤袖,所以第三行調(diào)用release時就會產(chǎn)生EXC_BAD_ACCESS錯誤。
在開啟ARC后昂验,可以很大程度上避免產(chǎn)生EXC_BAD_ACCESS錯誤捂敌,但也是有出現(xiàn)可能的,比如IOS里使用了C++代碼既琴,C++部分的對象是不會有ARC來管理的占婉。
EXC_BAD_ACCESS錯誤不像訪問空指針一樣容易定位,往往報錯時很難查找到錯誤點甫恩,所以XCode在Instruments中提供了單獨的Zombies工具來分析這類錯誤逆济。
使用Zombies分析的原理
和使用 Instruments的其他工具一樣,點擊XCode的Product菜單Profile啟動Instruments:
可以看到Zombies工具下邊的介紹,用于查找那些被過度釋放的僵尸對象奖慌。
Zombies工具的查找原理其實和設(shè)置NSZombieEnabled環(huán)境變量的調(diào)試方式是一樣的霎终,啟動Zombies后在內(nèi)部設(shè)置了NSZombieEnabled為True。
啟用了NSZombieEnabled的話升薯,它會用一個僵尸來替換默認(rèn)的dealloc實現(xiàn)莱褒,也就是在引用計數(shù)降到0時,該僵尸實現(xiàn)會將該對象轉(zhuǎn)換成僵尸對象涎劈。僵尸對象的作用是在你向它發(fā)送消息時广凸,就不會向之前那樣Crash或者產(chǎn)生 一個難以理解的行為,而是放出一個錯誤消息蛛枚,它會顯示一段日志并自動跳入調(diào)試器谅海, 因此我們就可以找到具體或者大概是哪個對象被錯誤的釋放了。
使用Zombies分析的步驟
1蹦浦、啟動Instruments扭吁,選擇Zombies;
2盲镶、對之前產(chǎn)生EXC_BAD_ACCESS的測試用例重新運行侥袜,直到程序崩潰,如果發(fā)生EXC_BAD_ACCESS錯誤溉贿,會出現(xiàn)以下界面:
3枫吧、通過滑動箭頭來查看錯誤細(xì)節(jié),例如可以看到該對象的內(nèi)存操作過程宇色,如malloc九杂、autorelease、retain宣蠕、release等操作例隆;
4、查看底部的詳細(xì)歷史抢蚀,選擇相應(yīng)的行可以定位到相應(yīng)的代碼镀层,找出產(chǎn)生錯誤的代碼:
基本上通過查看Zombies工具給出的信息找出錯誤代碼行是比較簡單的,Zombies也只有在產(chǎn)生EXC_BAD_ACCESS錯誤時才有用思币。
手動設(shè)置NSZombieEnabled環(huán)境變量:
XCode也提供了手動設(shè)置NSZombieEnabled環(huán)境變量的方法鹿响,不過設(shè)置NSZombieEnabled為True后羡微,會導(dǎo)致內(nèi)存占用的增長谷饿,同時會影響Leaks工具的調(diào)試,這是因為設(shè)置NSZombieEnabled會用僵尸對象來代替已釋放對象妈倔。
點擊Product菜單Edit Scheme打開該頁面博投,然后勾選Enable Zombie Objects 復(fù)選框:
一般不建議進(jìn)行進(jìn)行手動設(shè)置,而應(yīng)該使用Zombies工具進(jìn)行調(diào)試盯蝴。