Q:如何打印當前的函數和行號?
A:我們可以在打印時使用一些預編譯宏作為打印參數,來打印當前的函數和行號。如:
1
|
NSLog
(
@"%s:%d obj=%@"
, __func__, __LINE__, obj);
|
其中__func__和__LINE__都是預編譯的宏,編譯時會分別替換為當前函數和當前行號。
下面是一些常用於打印日志的宏。
宏 | 說明 |
---|---|
__func__ | 打印當前函數或方法,c字符串 |
__LINE__ | 打印當前行號,整數 |
__FILE__ | 打印當前文件路徑,c字符串 |
__PRETTY_FUNCTION__ | 打印當前函數或方法(在C++中會包含參數類型),c字符串 |
Q:如何打印一個類名,消息名,當前堆棧信息?
A:你可以使用以下方法在運行時動態獲取這些信息。
代碼 | 說明 |
---|---|
NSStringFromSelector(SEL) | 獲取selector的名字 |
NSStringFromSelector(_cmd) | 獲取當前方法名 |
NSStringFromClass([object class]) | 獲取object的類名 |
NSThread callStackSymbols] | 獲取當前線程的棧,是一個NSArry,包含堆棧中所有函數名。 |
Q:如何將日志打印到一個文件
A:可以使用freopen函數重定向標准輸出和標准出錯文件。因為printf函數會向標准輸出(stdout)打印,而NSLog函數會向標准出錯(stderr)打印。重新定向標准輸出(stdout)和標准出錯(stderr)到一個文件將會使他們打印日志到一個文件中。
1
2
|
freopen("/tmp/log
.txt
", "a+", stdout);
freopen("/tmp/log
.txt
", "a+", stderr);
|
#define NSLog(FORMAT, ...) {\
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];\
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];\
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];\
[dateFormatter setDateFormat:@"HH:mm:ss:SSSSSS"]; \
NSString *str = [dateFormatter stringFromDate:[NSDate date]];\
[dateFormatter release];\
fprintf(stderr,"[--%s--]*[--%s--]*[--%s:%d--]\n",[str UTF8String], [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String],[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__);\
}