硬廣:《IOS性能調優系列》第四篇,預計會有二十多篇,持續更新,歡迎關注。html
前兩篇《IOS性能調優系列:Analyze靜態分析》、《IOS性能調優系列:使用Instruments動態分析內存泄漏》關注了內存泄露的問題,本篇正好相反,關注的是內存中那些被過分釋放的對象(overreleased objects)。工具
這篇的標題糾結了半天,究竟是寫EXC_BAD_ACCESS錯誤調試,仍是寫內存中殭屍對象的分析,最後仍是選了個Duang~Duang~的標題。post
今天在論壇上看到個帖子,遇到的就是本篇要分析的問題,正好拿來解釋Bug場景:性能
相信在使用ARC以前,不少人遇到過EXC_BAD_ACCESS錯誤,這個錯誤能夠理解爲訪問了已被釋放的對象,蘋果稱之爲殭屍對象。測試
好比在不開啓ARC下,下面這段代碼:指針
NSString* hello = [NSString stringWithFormat:@"Hello"]; NSLog(@"What you say is %@",hello); [hello release];
hello對象不是手動分配,而是加入到自動釋放池,由釋放池負責釋放,因此第三行調用release時就會產生EXC_BAD_ACCESS錯誤。調試
在開啓ARC後,能夠很大程度上避免產生EXC_BAD_ACCESS錯誤,但也是有出現可能的,好比IOS裏使用了C++代碼,C++部分的對象是不會有ARC來管理的。日誌
EXC_BAD_ACCESS錯誤不像訪問空指針同樣容易定位,每每報錯時很難查找到錯誤點,因此XCode在Instruments中提供了單獨的Zombies工具來分析這類錯誤。orm
使用Zombies分析的原理htm
和使用 Instruments的其餘工具同樣,點擊XCode的Product菜單Profile啓動Instruments:
能夠看到Zombies工具下邊的介紹,用於查找那些被過分釋放的殭屍對象。
Zombies工具的查找原理其實和設置NSZombieEnabled環境變量的調試方式是同樣的,啓動Zombies後在內部設置了NSZombieEnabled爲True。
啓用了NSZombieEnabled的話,它會用一個殭屍來替換默認的dealloc實現,也就是在引用計數降到0時,該殭屍實現會將該對象轉換成殭屍對象。殭屍對象的做用是在你向它發送消息時,就不會向以前那樣Crash或者產生 一個難以理解的行爲,而是放出一個錯誤消息,它會顯示一段日誌並自動跳入調試器, 所以咱們就能夠找到具體或者大概是哪一個對象被錯誤的釋放了。
使用Zombies分析的步驟
一、啓動Instruments,選擇Zombies;
二、對以前產生EXC_BAD_ACCESS的測試用例從新運行,直到程序崩潰,若是發生EXC_BAD_ACCESS錯誤,會出現如下界面:
三、經過滑動箭頭來查看錯誤細節,例如能夠看到該對象的內存操做過程,如malloc、autorelease、retain、release等操做;
四、查看底部的詳細歷史,選擇相應的行能夠定位到相應的代碼,找出產生錯誤的代碼:
基本上經過查看Zombies工具給出的信息找出錯誤代碼行是比較簡單的,Zombies也只有在產生EXC_BAD_ACCESS錯誤時纔有用。
手動設置NSZombieEnabled環境變量:
XCode也提供了手動設置NSZombieEnabled環境變量的方法,不過設置NSZombieEnabled爲True後,會致使內存佔用的增加,同時會影響Leaks工具的調試,這是由於設置NSZombieEnabled會用殭屍對象來代替已釋放對象。
點擊Product菜單Edit Scheme打開該頁面,而後勾選Enable Zombie Objects 複選框:
通常不建議進行進行手動設置,而應該使用Zombies工具進行調試。
記錄,爲更好的本身!轉載請註明出處!