這算是在項目中最常用的命令了,方便程序員查看日志數據,便於程序調試。在開發中我們經常會進行一些設置,下面就來簡單的說一說:
先來看看普通的NSLog:
- (void)viewDidLoad { [super viewDidLoad]; // 准備的數據 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"TestNSLogData" ofType:@"plist"]; NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:filePath]; NSLog(@"%@", dict); }
輸出的結果為:
2017-03-09 16:27:24.270 DictionaryTest[11495:322828] { Person = { age = 20; name = "\U5f20\U4e09"; }; }
於是發現了一些令人不愉快的問題,下面就一個一個來解決吧。
首先解決日期輸出。有些時候我們需要一個干凈的日志輸出,可NSLog里自帶了一些東西,於是就得想辦法取消那些麻煩的輸出,只取我們需要的東西,所以在這里我們就使用了C語言了輸出方法了(printf / fprintf):
printf("%s", [[NSString stringWithFormat:@"%@", dict] UTF8String]);
輸出結果為:
{ Person = { age = 20; name = "\U5f20\U4e09"; }; }
現在輸出的結果就非常干凈了,而且還可以自己自定義,讓它滿足自己的風格,然后封裝成宏定義,自己看着舒服就OK。下面是我的宏定義:
#define NSLog(FORMAT, ...) fprintf(stderr, "\n\n******(class)%s(begin)******\n(SEL)%s\n(line)%zd\n(data)%s\n******(class)%s(end)******\n\n", [[[NSString stringWithUTF8String: __FILE__] lastPathComponent] UTF8String], __FUNCTION__, __LINE__, [[NSString stringWithFormat: FORMAT, ## __VA_ARGS__] UTF8String], [[[NSString stringWithUTF8String: __FILE__] lastPathComponent] UTF8String]);
輸出結果為:在這里顯示了類名,方法名,命令所在行數,數據
******(class)ViewController.m(begin)****** (SEL)-[ViewController viewDidLoad] (line)35 (data){ Person = { age = 20; name = "\U5f20\U4e09"; }; } ******(class)ViewController.m(end)******
然后再解決中文顯示的問題。在日志輸出中,中文輸出總顯示unicode編碼格式,不便於程序員閱讀。於是添加了兩行代碼:
- (void)viewDidLoad { [super viewDidLoad]; // 准備的數據 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"TestNSLogData" ofType:@"plist"]; NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:filePath]; // 數據格式轉換 NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil]; NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; NSLog(@"%@", jsonStr); }
輸出的結果為:
******(class)ViewController.m(begin)****** (SEL)-[ViewController viewDidLoad] (line)38 (data){ "Person" : { "age" : 20, "name" : "張三" } } ******(class)ViewController.m(end)******
這樣就能正確顯示中文了。但考慮到以后經常會使用到這兩行代碼,於是寫了一個NSObject的分類,將這個代碼封裝成一個方法,便於以后的使用。
// .h 文件 #import <Foundation/Foundation.h> @interface NSObject (Extension) - (NSString *)sjx_jsonString; @end /*---------- 華麗的分隔線 ----------*/ // .m 文件 #import "NSObject+Extension.h" @implementation NSObject (Extension) - (NSString *)sjx_jsonString { if (!self) return nil; // 數據格式轉換 NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self options:NSJSONWritingPrettyPrinted error:nil]; return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; } @end
這樣輸出時就這樣寫:
NSLog(@"%@", [dict sjx_jsonString]);
結果和上面一樣。
如果項目中使用到了MJExtension框架,這個分類其實也可以不必添加的,輸出的時候這樣寫:
NSLog(@"%@", [dict mj_JSONString]);
輸出的結果為:
******(class)ViewController.m(begin)****** (SEL)-[ViewController viewDidLoad] (line)38 (data){"Person":{"age":20,"name":"張三"}} ******(class)ViewController.m(end)******
只不過數據結構就不是那么好看,不過現在網上JSON在線編輯器也蠻多的,轉換一下就OK了。
最后考慮到性能問題。在項目上線發布的時候,項目里是不需要NSLog輸出的,所以需要設置一下DEBUG 和 RELEASE。
方法一:
方法二:使用項目中 xxxxxx.pch文件中添加宏定義,這也是項目中流行的做法:
#ifdef DEBUG #define NSLog(FORMAT, ...) fprintf(stderr, "\n\n******(class)%s(begin)******\n(SEL)%s\n(line)%zd\n(data)%s\n******(class)%s(end)******\n\n", [[[NSString stringWithUTF8String: __FILE__] lastPathComponent] UTF8String], __FUNCTION__, __LINE__, [[NSString stringWithFormat: FORMAT, ## __VA_ARGS__] UTF8String], [[[NSString stringWithUTF8String: __FILE__] lastPathComponent] UTF8String]); #else #define NSLog(FORMAT, ...) nil #endif
這樣就完美了。