這里記錄一下自己學(xué)習(xí)到的一些XCode調(diào)試的方法颈将。這些調(diào)試方法可以讓我們使用XCode編寫代碼進(jìn)行調(diào)試時用起來更順心應(yīng)手。
XCode的調(diào)試方法包括運行時設(shè)置斷點衔蹲,打印到控制臺,手寫命令打印等。
1. 運行時設(shè)置斷點
在XCode中需要觀察的變量所在的代碼處添加斷點注服,可以讓程序運行到這里暫停。這時鼠標(biāo)懸停在變量名處措近,XCode會顯示出該變量的信息溶弟。
斷點的類型分為異常斷點(Exception Breakpoint)和符號斷點(Symbolic Breakpoint)等,在XCode斷點瀏覽器(Breakpoints Navigator)的左下方可以添加這些斷點瞭郑。
符號斷點中的符號可以指方法名稱或函數(shù)名稱辜御。符號斷點可以中斷某個函數(shù)的調(diào)用。用戶還可以添加執(zhí)行斷點的條件屈张。
異常斷點可以使程序在每次發(fā)生異常時擒权,都會被中斷。一般用來捕獲未知異常阁谆。
2. 打印到控制臺
控制臺位于XCode的底端碳抄,用于打印程序運行過程中的輸出信息。在代碼中調(diào)用NSLog函數(shù)场绿,可以打印變量值到控制臺中顯示出來剖效。
NSLog(@"obj:%@", obj);
需要特別注意的是,盡管NSLog可圈可點,但在實際應(yīng)用中要防備其可能會引起安全問題璧尸,因為任何由NSLog輸出的內(nèi)容都會成為應(yīng)用程序成品代碼
的一部分咒林,也就是說會被任何接觸到應(yīng)用的人看到。只要把設(shè)備接入信息管理工具爷光,每個人都能查看控制臺信息并查詢每一條日志記錄垫竞。這可能會引發(fā)一系列嚴(yán)重后
果,例如向控制臺輸出機(jī)密邏輯算法或者用戶密碼等信息瞎颗。
我們可以使用宏來解決調(diào)用NSLog方法可能導(dǎo)致的安全問題件甥,只在調(diào)試版本中調(diào)用NSLog『甙危可以采用全局可訪問的頭文件引有,把所有日志記錄都灌進(jìn)去,而且不用擔(dān)心它們會出現(xiàn)在成品代碼當(dāng)中倦逐。
#ifdef DEBUG#define DMLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])#else#define DMLog(...) do { } while (0)
現(xiàn)在如果我們使用DMLog(這個名稱可以隨便起)譬正,它將只向調(diào)試版本輸出結(jié)果,任何成品代碼都不會受到影響檬姥。PRETTY_FUNCTION也幫上了大忙曾我,它會根據(jù)日志信息來源為函數(shù)命名。
3. 在控制臺端手寫命令打印
如果我們在應(yīng)用的特定點進(jìn)行中斷健民,一般來說是為了檢查對象的當(dāng)前狀態(tài)抒巢。Xcode為我們提供了一套“variables view(變量視圖)”,該視圖位于Xcode底部秉犹,與控制臺相鄰的左方區(qū)域蛉谜。理論上講它的作用是顯示與當(dāng)前環(huán)境相關(guān)的所有值的實時狀態(tài),但在實踐中有時無法列出值崇堵,或者是并未將值更新為中斷時的最新狀態(tài)型诚。幸運的是,我們可以利用一些非常實用的控制臺(console)命令自己進(jìn)行對象檢查工作鸳劳。1
po 命令:為 print object 的縮寫狰贯,顯示對象的文本描述。使用p 命令來處理純量值赏廓,即原生類型(boolean涵紊、integer、float等)幔摸。
print 命令:有點類似于格式化輸出摸柄,可以輸出對象的不同信息。
expr 表達(dá)式:打印表達(dá)式抚太。
info 命令:我們可以查看內(nèi)存地址所在信息塘幅。
info line *內(nèi)存地址:可以獲取內(nèi)存地址所在的代碼行相關(guān)信息昔案。
show 命令:顯示 GDB 相關(guān)的信息。如:show version 顯示GDB版本信息电媳。
bt: 顯示當(dāng)前進(jìn)程的函數(shù)調(diào)用棧的情況踏揣;”up num”:查看調(diào)用的詳細(xì)信息;down:返回棧列表匾乓;l:顯示詳細(xì)代碼信息捞稿;p:輸出數(shù)值。
help 命令:如果忘記某條命令的語法了拼缝,用來獲取幫助信息娱局。
需要注意的是,上述這些都是GDB的調(diào)試命令咧七,在LLDB中會有所差異衰齐。隨著Xcode 5的發(fā)布,LLDB調(diào)試器已經(jīng)取代了GDB继阻,成為了Xcode工程中默認(rèn)的調(diào)試器耻涛。
這里需要強(qiáng)調(diào)的一個技巧是,通過使用expr 表達(dá)式可實現(xiàn)在運行時修改變量的值瘟檩。2
expr username = @"username"expr password = @"badpassword"
通過上面的代碼段抹缕,變量username和password分別被重新賦值。
4. 設(shè)置NSZombieEnabled墨辛、MallocStackLogging卓研、NSAutoreleaseFreedObjectCheckEnabled、NSDebugEnabled
第一種設(shè)置方法:
1. Product->Edit Scheme...->Run...->EnvironmentVariables.
2. add NSZombieEnabled睹簇,set the value with YES
3. add MallocStackLogging, set the value with YES.
4. add NSAutoreleaseFreedObjectCheckEnabled, set the value with YES.
5. add NSDebugEnabled, set the value with YES.
使用場景:
主要為了解決EXC_BAD_ACCESS問題奏赘,MallocStackLogging用來啟用malloc記錄(使用方式 malloc_history${App_PID}${Object_instance_addr})。
第二種設(shè)置方法:
直接通過Editing Scheme窗口中的Run選項下的Diagnostics選項卡來設(shè)置带膀。
需要注意的問題:
NSZombieEnabled只能在調(diào)試的時候使用志珍,千萬不要忘記在產(chǎn)品發(fā)布的時候去掉橙垢,因為NSZombieEnabled不會真正去釋放dealloc對象的內(nèi)存垛叨。
5. 重寫respondsToSelector方法
實現(xiàn)方式
#ifdef _FOR_DEBUG_-(BOOL) respondsToSelector:(SEL)aSelector {? ? printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]);return[super respondsToSelector:aSelector]; }#endif
使用方法:
需要在每個object的.m或者.mm文件中加入上面代碼(應(yīng)該可以使用類屬實現(xiàn)),并且在other c flags中加入-DFOR_DEBUG(記住請只在Debug Configuration下加入此標(biāo)記)柜某。這樣當(dāng)你程序崩潰時嗽元,XCode的console上就會準(zhǔn)確地記錄了最后運行的object的方法。
http://mobile.51cto.com/iphone-377138.htm“iOS故障排除指南:基本技巧”
http://my.oschina.net/notting/blog/115294“Xcode LLDB Debug教程”
http://www.2cto.com/kf/201210/162934.html“Xcode調(diào)試攻略”