最近看到朋友的一个将
NSDictionary
、NSArray
以及NSSet
的NSLog
输出的Unicode
直接转换为中文的小工具,恍然回神,这类问题的解决方案看了很多,但是原因呢?思前想后,各种搜索,最终只有找到一篇有点接近的文章,大家可以去看看这篇文章。
摘自原文:
虽然我们不知道NSDictionary
究竟是怎么实现description
方法的,但是官方文档中好像给出了一点蛛丝马迹:
description
A string that represents the contents of the dictionary, formatted as a <u>property list</u> (read-only).
这里说到了property list
。根据property list
的文档,它可以被写作三种形式:XML
、二进制和ASCII
。浏览了一下它们的文档后,感觉ASCII
格式与我们看到的、打印出来的NSDictionary
相似。且在讲到用ASCII来表示NSString时,文档中提到:
Though the property list format uses ASCII for strings, note that Cocoa uses Unicode. Since string encodings vary from region to region, this representation makes the format fragile. You may see strings containing unreadable sequences of ASCII characters; these are used to represent Unicode characters.
这样,我们也就不难猜测出,导致不能直接输出中文的原因,就是因为description
显示所使用的格式问题。
然而,知道了原因(虽然也是没办法达到拨开云雾见青天的效果),我们也要知道怎么解决它,正如我前面所说,解决的方法网上一抓一大把,常见的两种方式:
NSJSONSerialization
NSDictionary* dic = @{@"名字":@"杰克",
@"年龄":@20};
NSData* dicData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
NSString* dicStr = [[NSString alloc]initWithData:dicData encoding:NSUTF8StringEncoding];
先将字典转换为二进制,再将二进制转换为UTF8
编码格式,这样,中文就能直接NSLog
出来了。
Category
创建一个空的OC文件,在里面重写NSDictionary
和NSArray
的- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
方法:
@implementation NSDictionary (Log)
- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
NSMutableString *mStr = [NSMutableString string];
NSMutableString *tab = [NSMutableString stringWithString:@""];
for (int i = 0; i < level; i++) {
[tab appendString:@"\t"];
}
[mStr appendString:@"{\n"];
NSArray *allKey = self.allKeys;
for (int i = 0; i < allKey.count; i++) {
id value = self[allKey[i]];
NSString *lastSymbol = (allKey.count == i + 1) ? @"":@";";
if ([value respondsToSelector:@selector(descriptionWithLocale:indent:)]) {
[mStr appendFormat:@"\t%@%@ = %@%@\n",tab,allKey[i],[value descriptionWithLocale:locale indent:level + 1],lastSymbol];
} else {
[mStr appendFormat:@"\t%@%@ = %@%@\n",tab,allKey[i],value,lastSymbol];
}
}
[mStr appendFormat:@"%@}",tab];
return mStr;
}
@end
@implementation NSArray (Log)
- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
NSMutableString *mStr = [NSMutableString string];
NSMutableString *tab = [NSMutableString stringWithString:@""];
for (int i = 0; i < level; i++) {
[tab appendString:@"\t"];
}
[mStr appendString:@"(\n"];
for (int i = 0; i < self.count; i++) {
NSString *lastSymbol = (self.count == i + 1) ? @"":@",";
id value = self[i];
if ([value respondsToSelector:@selector(descriptionWithLocale:indent:)]) {
[mStr appendFormat:@"\t%@%@%@\n",tab,[value descriptionWithLocale:locale indent:level + 1],lastSymbol];
} else {
[mStr appendFormat:@"\t%@%@%@\n",tab,value,lastSymbol];
}
}
[mStr appendFormat:@"%@)",tab];
return mStr;
}
@end