最基本的調(diào)試是NSLog及DEBUG預(yù)處理器宏
在系統(tǒng)控制臺(tái)顯示日志信息運(yùn)行應(yīng)用程序時(shí)是最早調(diào)試機(jī)制之一,利用log
你可以查看應(yīng)用程序的運(yùn)行記錄鸠儿,當(dāng)程序運(yùn)行完畢宦赠,你可以長時(shí)間查看胸嘴。此外券犁,您的應(yīng)用程序運(yùn)行期間埠对,可以觀察所產(chǎn)生并寫入到控制臺(tái)络断,在您的應(yīng)用程序它們所描述正在發(fā)生的事件的日志消息。作為一個(gè)開發(fā)者你是用NSLog
的在console
中顯示的文本和信息的完全控制權(quán)项玛,log
可以發(fā)現(xiàn)即使是最難查找一個(gè)應(yīng)用程序的問題.
此文檔關(guān)于有關(guān)NSLog的功能及DEBUG預(yù)處理程序宏實(shí)際考慮為調(diào)試有用的對(duì)話
下面是NSLog
調(diào)用的一個(gè)例子貌笨。
NSString *message = @"test message";
NSLog( @"Here is a test message: '%@'", message );
并且,對(duì)于上述說法襟沮,控制臺(tái)輸出將顯示如下:
Here is a test message: 'test message'
這真的就是這么簡(jiǎn)單锥惋!而且,在這個(gè)文件中的這個(gè)時(shí)刻开伏,你現(xiàn)在有足夠的信息來開始使用NSLog的調(diào)試您的應(yīng)用程序.但是膀跌,你應(yīng)該繼續(xù)往下看:在本文檔的剩余部分補(bǔ)充說,你可以使用授權(quán)您可以在您的項(xiàng)目更有效地使用記錄更多詳細(xì)信息固灵。
此文檔適用于所有iOS和OS X開發(fā),本示例假定正在使用Xcode的讀者捅伤,是熟悉的Objective-C語言,并了解使用C語言預(yù)處理程序的基礎(chǔ)知識(shí)巫玻。
[TOC]
在哪里可以找到NSLog的輸出
有史以來Founction
框架的NSLog
功能一直適用于iOS
和OSX
的個(gè)個(gè)版本丛忆。因此祠汇,您可以依賴它是可用于在任何蘋果的平臺(tái),讓您的應(yīng)用程序?qū)⑦\(yùn)行調(diào)試用的熄诡。NSLog
的輸出消息記錄到蘋果系統(tǒng)日志工具或控制臺(tái)應(yīng)用程序(通常以時(shí)間及進(jìn)程ID作為前綴)可很。許多系統(tǒng)框架中使用NSLog的用于記錄異常和錯(cuò)誤,但不要求來限制及其使用于上述目的這也是完全可以接受的使用NSLog的輸出變量值凰浮,參數(shù)根穷,函數(shù)結(jié)果,堆棧跟蹤等信息导坟,所以你可以看到什么是在你的代碼在運(yùn)行時(shí)發(fā)生屿良。
控制臺(tái)輸出可以出現(xiàn)在許多地方,包括(但不限于)Xcode和控制臺(tái)應(yīng)用程序惫周,參考有關(guān)從您的應(yīng)用程序的調(diào)用NSLog的找到控制臺(tái)輸出的更多信息尘惧,請(qǐng)參見技術(shù)Q&A QA1747:調(diào)試部署iOS應(yīng)用
如何調(diào)用NSLog的
該Founction
框架NSLog功能的工作就像標(biāo)準(zhǔn)C庫printf函數(shù),最大的區(qū)別在于格式字符串被指定為“* NSString的”類型的值递递,而不是C風(fēng)格的字符串
簡(jiǎn)單的例子
這里是展示如何調(diào)用NSLog的一個(gè)例子:
NSString *outputData = @"A quick brown fox jumps over a lazy dog!";
NSLog( @"text: %@", outputData );
/* Comment:
@"text: %@" - is the printf style formatting template for output (an NSString *)
outputData - refers to to the text we wish to display (also an NSString *)
*/
而且喷橙,這里是輸出的顯示方式:
text: A quick brown fox jumps over a lazy dog!
高級(jí)詳細(xì)信息
出現(xiàn)用于NSLog的函數(shù)定義如下:
void NSLog(NSString *format, ...);
注意第一個(gè)參數(shù)是一個(gè)格式化字符串,它可以含有意味著額外的參數(shù)之后期望特殊的替換標(biāo)記.如果關(guān)心和關(guān)注不能采取措施登舞,確保格式字符串的內(nèi)容匹配起來贰逾,其余的參數(shù),您的應(yīng)用程序可能會(huì)崩潰(或者菠秒,至少是疙剑,它將輸出不可用的數(shù)據(jù)到控制臺(tái))
像printf函數(shù),使用NSLog的標(biāo)記替換:
然而践叠,出現(xiàn)在Objective-C
言缤,%@
,用于指示及其對(duì)應(yīng)的參數(shù)應(yīng)該是一個(gè)Objective-C
的對(duì)象一個(gè)額外取代標(biāo)記提供禁灼。
除了%@
替換標(biāo)識(shí)所有常規(guī)的printf
風(fēng)格替換標(biāo)記是供您使用
關(guān)于有關(guān)NSLog的使用的替換標(biāo)記的詳細(xì)信息管挟,請(qǐng)參見“字符串編程指南”的“字符串格式說明”部分。
好東西要在日志文件包括
日志記錄允許您創(chuàng)建描述您的應(yīng)用程序弄捕,你可以在你的閑暇之后分析操作的抄本僻孝。因此,你想在你的日志盡可能多的有用信息守谓,這樣更容易在你的應(yīng)用程序運(yùn)行期間讓你真正看到正在發(fā)生的事情穿铆。
下面是一些通常包含在一些解釋日志的一些項(xiàng)目:
邏輯和分支
新增您代碼的邏輯內(nèi)部的日志語句將幫助您了解正在被執(zhí)行的部分,并正在使用你的邏輯分飞,分支機(jī)構(gòu)
日志對(duì)于十分復(fù)雜的程序落實(shí)十分有用的悴务,你可以看到運(yùn)行期間的程序邏輯。
獨(dú)特且易于查找文本模式
在每個(gè)日志聲明,它是有用的讯檐,包括一些獨(dú)特的并且容易找到的文本模式羡疗,所以如果你確定該日志語句有問題,可以很容易地通過你的源文件搜索和找到它的位置
變量和屬性值
你在你的應(yīng)用程序關(guān)鍵地方打印變量和屬性可以驗(yàn)證這些值是否是允許的范圍之內(nèi)别洪。在日志打印錯(cuò)誤信息叨恨,可以幫助你識(shí)別超出值范圍的這一種情況。
除了用%@
標(biāo)記挖垛,任何在Printf
使用的標(biāo)記都可以在格式化字符串中使用痒钝。這將允許您顯示許多不同類型的值,更多關(guān)于格式化信息你可以參考“字符串編程指南”的“字符串格式說明”部分
printf函數(shù)提供了大量用于打印數(shù)字替換標(biāo)記(例如%d痢毒,%ld送矩,%f)為方便起見,你可以使用Objective-C的
Box能力
哪替,以節(jié)省時(shí)間栋荸,避免編譯器警告。例如凭舶,以下內(nèi)容:
double myNumber = 7.7;
NSLog(@"number: %@", @(myNumber));
打印如下
number: 7.7
這種技術(shù)適用于所有數(shù)字類型晌块,編譯器意識(shí)到(或簽定任何大小的無符號(hào)整數(shù)或浮點(diǎn)數(shù) - 8,16帅霜,32或64位)匆背,并且將任何必要的強(qiáng)制類型轉(zhuǎn)換為你而不會(huì)產(chǎn)生的任何編譯器警告
誰正在被調(diào)用
分析應(yīng)用程序的操作是至關(guān)重要的,你可以知道那些程序那些功能被順序調(diào)用身冀。在這種情況下钝尸,它是添加接近的方法和函數(shù)定義之初即只需打印出函數(shù)名稱的聲明NSLog的一個(gè)很好的主意。
- (void)pressButton:(id)sender
{
NSLog( @"calling: %s", __PRETTY_FUNCTION__ );
....
這里闽铐,預(yù)定義的編譯時(shí)間變量PRETTY_FUNCTION(一個(gè)C風(fēng)格字符串)被用于打印函數(shù)的名稱調(diào)用.當(dāng)你分析大量的功能代碼蝶怔,你想知道正在調(diào)用你代理方法的層次是非常有用的。
以上將打印在console以下內(nèi)容:
calling: -[MyObjectClassName pressButton:]
該PRETTY_FUNCTION編譯time變量和其他類似在技術(shù)Q&A QA1669討論:改進(jìn)了日志記錄在Objective-C兄墅。
記錄你的堆棧信息
當(dāng)檢查崩潰日志,在堆棧中是非常寶貴找出導(dǎo)致的任何特定情況下的連鎖事件澳叉。當(dāng)使用NSLog
進(jìn)行調(diào)試隙咸,您可以通過調(diào)用NSThread-callStackSymbols
類方法隨時(shí)檢索當(dāng)前堆棧跟蹤的副本。你可以在堆棧中使用%@
打印NSArray
的堆棧的信息成洗。
NSLog(@"%@", [NSThread callStackSymbols]);
上面的語句輸出是下面的樣子五督。
2014-04-30 18:44:30.075 AVCustomEdit[52779:60b] (
0 AVCustomEdit 0x0000efa6 -[APLSimpleEditor buildCompositionObjectsForPlayback:] + 278
1 AVCustomEdit 0x0000686e -[APLViewController viewDidAppear:] + 590
2 UIKit 0x007a4099 -[UIViewController _setViewAppearState:isAnimating:] + 526
3 UIKit 0x007a4617 -[UIViewController __viewDidAppear:] + 146
4 UIKit 0x007a49aa -[UIViewController _executeAfterAppearanceBlock] + 63
5 UIKit 0x0069f0d0 ___afterCACommitHandler_block_invoke_2 + 33
6 UIKit 0x0069f055 _applyBlockToCFArrayCopiedToStack + 403
7 UIKit 0x0069ee9a _afterCACommitHandler + 568
8 CoreFoundation 0x029db2bf __CFRunLoopDoObservers + 399
9 CoreFoundation 0x029b9254 __CFRunLoopRun + 1076
10 CoreFoundation 0x029b89d3 CFRunLoopRunSpecific + 467
11 CoreFoundation 0x029b87eb CFRunLoopRunInMode + 123
12 GraphicsServices 0x0318b5ee GSEventRunModal + 192
13 GraphicsServices 0x0318b42b GSEventRun + 104
14 UIKit 0x00681f9b UIApplicationMain + 1225
15 AVCustomEdit 0x000026bd main + 141
16 libdyld.dylib 0x0269e701 start + 1
)
該DEBUG預(yù)處理程序宏
簡(jiǎn)而言之,該DEBUG處理器宏作用一樣瓶殃,你可以打開和關(guān)閉一部分的調(diào)試代碼充包。具體地,Debug
宏旨在被用于打開和關(guān)閉相關(guān)的調(diào)試中不同部分源代碼.在Xcode的默認(rèn)配置中,調(diào)試默認(rèn)為1,發(fā)布為0.而且基矮,你可以利用它來自動(dòng)地包含額外的調(diào)試和記錄代碼的調(diào)試版本淆储。
下面是Debug
使用的一個(gè)例子。
- (void)pressButton:(id)sender
{
#if DEBUG
NSLog(@"preparing to press button!");
#endif
[self prepareForButtonPress];
#if DEBUG
NSLog(@"pressing button!");
#endif
[self activatePressButtonSequence:self withCompletion:^{
#if DEBUG
NSLog(@"button sequence complete.");
#endif
[self buttonPowerDown];
}];
NSLog(@"This line has no DEBUG macro, so it gets printed in both debug and release builds!");
}
調(diào)試版本(DEBUG == 1)
將輸出下面的信息
preparing to press button!
pressing button!
button sequence complete.
This line has no DEBUG macro, so it gets printed in both debug and release builds!
發(fā)布版本(DEBUG == 0)
將輸出下面的信息
This line has no DEBUG macro, so it gets printed in both debug and release builds!
NSLog
需要時(shí)間去執(zhí)行家浇,如果你在你的應(yīng)用程序里面加了很多這樣的代碼本砰,將加大你程序的運(yùn)行時(shí)間。在測(cè)試過程中钢悲,這通常不是問題点额。但是在發(fā)布的時(shí)候最好刪除所有的打印,讓用戶體驗(yàn)最好的性能莺琳,不是打印一大堆看不懂的信息还棱。正因?yàn)槿绱耍_發(fā)者可以使用Debug
宏可以讓NSLog
只有在調(diào)試的時(shí)候出現(xiàn)惭等。
在Xcode里面的DEBUG
宏
在Xcode中DEBUG
定義調(diào)試模式珍手,預(yù)編譯宏可以編譯DEBUG
可以讓你DEBUG
模式運(yùn)行程序。如果你不確定你是否定義了咕缎,可以通過打開你工程Build Setting
搜索預(yù)處理珠十,確保在Debug
模式DEBUG ==1
。如果還沒有定義凭豪,你可以手動(dòng)的添加焙蹭,預(yù)編譯宏是區(qū)分大小寫的。
? 圖一在Xcode設(shè)置DEBUG
預(yù)編譯宏
添加更多的LOG
如果你已經(jīng)添加了log
你還是找不到問題的所在嫂伞,你可以添加很多的Log
去查找孔厉。繼續(xù)添加記錄到您的應(yīng)用程序,直到你能夠獲取足夠的信息帖努,以便您能夠明白發(fā)生了什么撰豺。
NSLog是調(diào)試的朋友
每一個(gè)iOS
或者OSX
的開發(fā)人員無時(shí)無刻的使用NSLog
調(diào)試你的程序,而且拼余,你知道開發(fā)者可能對(duì)如何使用它的一些有趣的想法可能對(duì)你有幫助污桦。如果您對(duì)NSLog的任何其他問題或需要幫助調(diào)試,請(qǐng)?jiān)儐柲膯栴}在適當(dāng)?shù)腗ac或iOS開發(fā)者論壇調(diào)試的部分匙监。
如果您對(duì)本文有任何意見凡橱,請(qǐng)通過反饋標(biāo)簽提交的文檔的底部