#define DLog(format, ...) do { \
fprintf(stderr,"<%s : %s : %d> %s\n", \
[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], \
__FUNCTION__, __LINE__, \
[[NSString stringWithFormat:format, ##__VA_ARGS__] UTF8String]); \
} while (0)
在iOS開發(fā)中,很大一部分時(shí)間我們通過控制器的Log信息調(diào)試我們的項(xiàng)目,很多情況下我們會(huì)對(duì)這行Log信息所處的文件位置(文件名)、方法、行數(shù)信息非常關(guān)系,上面自定義的宏就滿足了我們的大部分需求了。
下面,我們就來說說它。
1.DLog(format, ...)
我們看到的是一個(gè)函數(shù)宏【宏分類:對(duì)象宏(object-like macro)和函數(shù)宏(function-like macro)】,但是它的參數(shù)比較奇怪,第二個(gè)參數(shù)是...,在宏定義(其實(shí)也包括函數(shù)定義)的時(shí)候,寫為...的參數(shù)被叫做可變參數(shù)(variadic)??勺儏?shù)的個(gè)數(shù)不做限定。在這個(gè)宏定義中,除了第一個(gè)參數(shù)format將被單獨(dú)處理外,接下來輸入的參數(shù)將作為整體一并看待?;叵胍幌翹SLog的用法,我們?cè)谑褂肗SLog時(shí),往往是先給一個(gè)format字符串作為第一個(gè)參數(shù),然后根據(jù)定義的格式在后面的參數(shù)里跟上寫要輸出的變量之類的。這里第一個(gè)格式化字符串即對(duì)應(yīng)宏里的format,后面的變量全部映射為...作為整體處理。
2.fprintf
fprintf(<#FILE *restrict#>, <#const char *restrict, ...#>)
int fprintf (FILE *restrict, const char *restrict, [argument])
FILE *restrict:文件指針;
const char *restrict:輸出格式化說明符(可參考我的博客C語言格式化說明符)
[argument]:附加參數(shù)列表;
可以看到 "FILE *restrict" ,這個(gè)參數(shù)我們使用的宏 “stderr”
含義:【unix】標(biāo)準(zhǔn)輸出(設(shè)備)文件,默認(rèn)輸出到終端窗口。
FILE : 文件的完整路徑和文件名(絕對(duì)路徑)。
LINE:當(dāng)前行數(shù)。
FUNCTION:當(dāng)前調(diào)用的方法或函數(shù)名。
由于文件路徑中可能會(huì)存在中文,所以我們需要對(duì)獲取到的路徑進(jìn)行UTF-8轉(zhuǎn)碼,第二次轉(zhuǎn)碼轉(zhuǎn)為C字符串類型 ‘const char *’類型:
[[[NSString stringWithUTF8String:FILE] lastPathComponent] UTF8String]
VA_ARGS:表示的是宏定義中的...中的所有剩余參數(shù)。在這里展開的時(shí)候編譯器會(huì)將VA_ARGS直接替換為輸入中從第二個(gè)參數(shù)開始的剩余參數(shù)。
符號(hào)## :表示將前面的格式化字符串和后面的參數(shù)列表合并。
————————————————