為了方便調(diào)試我們經(jīng)常需要在控制臺(tái)打印數(shù)組/字典信息,但是如果含有中文,打印出來的就是一堆看不懂的信息(其實(shí)是Unicode編碼),影響開發(fā)效率.
本文目標(biāo):
- 使用NSLog能打印中文字典/數(shù)組
- 在控制臺(tái)使用
po
命令 顯示的調(diào)試信息也是中文的
2016-12-2 更新
- 支持對(duì)控件的打印,比如view.subviews
- 運(yùn)用的是方法交換,只是對(duì)系統(tǒng)的debugDescription方法做轉(zhuǎn)碼處理,因此格式保留為系統(tǒng)風(fēng)格
- 只在DEBUG模式下有效,對(duì)線上版本無干擾
效果:
如何使用
直接拖進(jìn)項(xiàng)目中去即可.非常簡(jiǎn)單.
解決NSLog打印中文問題
對(duì)于NSLog能打印中文字典/數(shù)組這個(gè)問題,首先看看網(wǎng)上的普通做法: 就是重新寫一個(gè)字典和數(shù)組的分類,重寫他們的- (NSString *)descriptionWithLocale:(id)locale
這個(gè)方法
代碼如下:
@implementation NSDictionary (Log)
- (NSString *)descriptionWithLocale:(id)locale
{
NSMutableString *string = [NSMutableString string];
// 開頭有個(gè){
[string appendString:@"{\n"];
// 遍歷所有的鍵值對(duì)
[self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOLBOOL *stop) {
[string appendFormat:@"\t%@", key];
[string appendString:@" : "];
[string appendFormat:@"%@,\n", obj];
}];
// 結(jié)尾有個(gè)}
[string appendString:@"}"];
// 查找最后一個(gè)逗號(hào)
NSRange range = [string rangeOfString:@"," options:NSBackwardsSearch];
if (range.location != NSNotFound)
[string deleteCharactersInRange:range];
return string;
}
@end
@implementation NSArray (Log)
- (NSString *)descriptionWithLocale:(id)locale
{
NSMutableString *string = [NSMutableString string];
// 開頭有個(gè)[
[string appendString:@"[\n"];
// 遍歷所有的元素
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOLBOOL *stop) {
[string appendFormat:@"\t%@,\n", obj];
}];
// 結(jié)尾有個(gè)]
[string appendString:@"]"];
// 查找最后一個(gè)逗號(hào)
NSRange range = [string rangeOfString:@"," options:NSBackwardsSearch];
if (range.location != NSNotFound)
[string deleteCharactersInRange:range];
return string;
} 性能呢
@end
```
這樣做可以解決問題,但是存在個(gè)問題:
* 打印出來的格式不規(guī)范,看起來別扭,括號(hào),大括號(hào)位置基本沒法對(duì)上.
說說我的思路:基本上和上面的一致,需要重寫`- (NSString *)descriptionWithLocale:(id)locale`這個(gè)方法,不同的是,直接調(diào)用`self的description`方法,然后對(duì)返回的字符串進(jìn)行處理,將其轉(zhuǎn)換為中文.
代碼如下:
給NSString寫的分類處理Unicode的編碼
```
- (NSString *)unicodeString{
NSString *tempStr1 = [self stringByReplacingOccurrencesOfString:@"\\u" withString:@"\\U"];
NSString *tempStr2 = [tempStr1 stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
NSString *tempStr3 = [[@"\"" stringByAppendingString:tempStr2] stringByAppendingString:@"\""];
NSData *tempData = [tempStr3 dataUsingEncoding:NSUTF8StringEncoding];
NSPropertyListFormat format = NSPropertyListOpenStepFormat;
NSString *returnStr = [NSPropertyListSerialization propertyListWithData:tempData options:NSPropertyListImmutable format:&format error:nil];
return [returnStr stringByReplacingOccurrencesOfString:@"\\r\\n" withString:@"\n"];
}
```
給NSDictionary和NSArray寫的分類中:
```
- (NSString *)descriptionWithLocale:(id)locale{
return self.description.unicodeString;
}
```
到此,用NSLog就能打印出規(guī)范的中文了,效果如下:
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1666610-d20ac35500d0fca3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
####解決控制臺(tái)調(diào)試命令`po`出來的不是中文問題:
方案和上面的基本差不多,能用系統(tǒng)的方法就用系統(tǒng)的,畢竟系統(tǒng)的穩(wěn)定,速度快.
原理:使用'po'命令會(huì)調(diào)用`debugDescription`這個(gè)方法,這個(gè)返回調(diào)試環(huán)境下的信息,不建議重寫`description`這個(gè)方法.
代碼如下:
```
- (NSString *)descriptionWithLocale:(id)locale{
return self.description.unicodeString;
}
- (NSString *)debugDescription{
return self.description.unicodeString;
}
```
到此,使用`po`命令就可以查看包含中文的信息了.
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1666610-18505aeae078ea48.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
附上最終github鏈接直接拖到項(xiàng)目中即可使用:<https://github.com/iOSSinger/CNLog>