解决NSLog字典,数组,集合时中文显示Unicode问题

前言

平时开发调试时,NSLog( )函数肯定没少用,不管是打印服务器返回的JSON数据,还是打印自己构造的数据。但是,当NSDictionaryNSArrayNSSet中有中文字符时,NSLog输出的是中文的Unicode码:

1)NSDictionary :
   NSDictionary *dict = @{
                           @"名字" : @"杰克",
                           @"年龄" : @20,
                         }; 
   NSLog(@"%@", dict);
NSDictionary中有中文时的输出
2)NSArray :
    NSArray *array = @[
                       @"语文",
                       @"数学",
                       @"外语",
                       ];
   NSLog(@"%@", array);
NSArray中有中文时的输出
3)NSSet :
    NSMutableSet *mSet = [NSMutableSet set];
    [mSet addObject:@"语文"];
    [mSet addObject:@"数学"];
    [mSet addObject:@"外语"];
    NSLog(@"%@", mSet);

NSSet中有中文时的输出

关于 NSSet,上面的输出还不是最糟的,再来看看这个:

    NSMutableSet *mSet = [NSMutableSet set];
    [mSet addObject:@"语文"];
    [mSet addObject:@"数学"];
    [mSet addObject:@"外语"];

    NSMutableArray *mArray = @[].mutableCopy;
    [mArray addObject:mSet];
    NSLog(@"%@", mArray);
NSArray中嵌套NSSet时的输出

解决方法

1. NSJSONSerialization

调用NSJSONSerialization的类方法,将NSDictionaryNSArray对象转换成JSON格式的NSData数据,再将NSData数据转成NSString输出。

+ (nullable NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;

opt参数传NSJSONWritingPrettyPrinted这个枚举值

NSDictionary的输出:

    NSDictionary *dict = @{
                           @"名字" : @"杰克",
                           @"年龄" : @20,
                      };
    
    NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding
    NSLog(@"%@",str);
NSJSONSerialization之后的NSDictionary的输出

NSArray的输出:

    NSArray *array = @[
                       @"语文",
                       @"数学",
                       @"外语",
                       ];
    
    NSData *data = [NSJSONSerialization dataWithJSONObject:array options:NSJSONWritingPrettyPrinted error:nil];
    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"%@",str);

NSSet的输出:

    NSMutableSet *mSet = [NSMutableSet set];
    [mSet addObject:@"语文"];
    [mSet addObject:@"数学"];
    [mSet addObject:@"外语"];
    
    // 这一行将使程序crash,因为NSSet的对象找不到对应的JSON格式的数据
    NSData *data = [NSJSONSerialization dataWithJSONObject:mSet options:NSJSONWritingPrettyPrinted error:nil];
    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"%@",str);

NSJSONSerialization之后的NSSet,程序crash

程序crash的原因是JSONObject不支持 NSSet类型,因为 NSSet的对象找不到对应的JSON格式的数据

2. Category

NSDictionay,NSArray,NSSet类型的实例用NSLog输出时,都会调用

- (NSString *)descriptionWithLocale:(id)locale

只需分别创建NSDictionayNSArrayNSSet的Category,覆盖系统的- (NSString *)descriptionWithLocale:(id)locale方法,当NSLog时,系统将会调用我们创建的Category中的方法。
- (NSString *)descriptionWithLocale:(id)locale方法中创建NSMutableString的实例,逐个拼接集合对象中的元素。这三个Category,我已经写好了放在Github上了将Demo中的Foundation+Log.m文件添加到工程中,我们再来看看NSDictionayNSArrayNSSet实例的输出。

1)NSDictionary
    NSDictionary *dict = @{
                           @"名字" : @"杰克",
                           @"年龄" : @20,
                           };
    NSLog(@"%@", dict);
NSDictionary中有中文时的输出
2)NSArray
    NSArray *array = @[
                       @"语文",
                       @"数学",
                       @"外语",
                       ];
    
    NSLog(@"%@", array);
NSArray中有中文时的输出
3)NSSet
    NSMutableSet *mSet = [NSMutableSet set];
    [mSet addObject:@"语文"];
    [mSet addObject:@"数学"];
    [mSet addObject:@"外语"];
    
    NSLog(@"%@", mSet);
NSSet中有中文时的输出
4)NSDictionary + NSArray
    NSDictionary *dict = @{@"名字" : @"杰克",
                           @"年龄" : @12,
                           @"内容" : @{
                                   @"userName" : @"rose",
                                   @"message" : @"好好学习",
                                   @"testArray" : @[@"数学",
                                                    @"英语",
                                                    @"历史",
                                                    @[
                                                        @"zhangsan",
                                                        @"lisi",
                                                        @[
                                                            @"test1",
                                                            @"test2",
                                                            @"test3"
                                                            ],
                                                        ],
                                                    ],
                                   @"test" : @{
                                           @"key1" : @"测试1",
                                           @"键值2" : @"test2",
                                           @"key3" : @"test3"
                                           }
                                   
                                   },
                           
                           
                           };
    NSLog(@"%@", dict);
解决NSLog字典,数组,集合时中文显示Unicode问题_第1张图片
NSDictionary + NSArray有中文时的输出
5)NSSet + NSArray
    NSMutableSet *mSet = [NSMutableSet set];
    [mSet addObject:@"语文"];
    [mSet addObject:@"数学"];
    [mSet addObject:@"外语"];
    
    NSMutableArray *mArray = @[].mutableCopy;
    [mArray addObject:mSet];
    
    NSLog(@"%@", mArray);
解决NSLog字典,数组,集合时中文显示Unicode问题_第2张图片
NSSet + NSArray有中文时的输出
6)NSSet + NSArray + NSDictionary
    NSMutableSet *mSet = [NSMutableSet set];
    [mSet addObject:@"英语"];
    [mSet addObject:@"历史"];
    [mSet addObject:@"数学"];
    
    NSArray *arr = @[@"a", @"b", @"c"];
    [mSet addObject:arr];
    
    NSMutableSet *subSet = mSet.mutableCopy;
    NSMutableSet *subSubSet = mSet.mutableCopy;
    [subSet addObject:subSubSet];
    [mSet addObject:subSet];
    
    NSDictionary *subDict = @{
                              @"键0" : @"值0",
                              @"键1" : @"值1",
                              @"键2" : @"值2",
                              };
    [mSet addObject:subDict];
    NSDictionary *dict = @{@"something" : mSet};
    
    NSLog(@"%@", dict);
解决NSLog字典,数组,集合时中文显示Unicode问题_第3张图片
NSSet + NSArray + NSDictionary有中文时的输出

性能

对比我实现的Category方法和系统方法的执行时间

- (void)testPerformanceExample
{
    // This is an example of a performance test case.
    [self measureBlock:^{
        // Put the code you want to measure the time of here.
        for (NSInteger i = 0; i < 1000; ++i) {
            NSMutableSet *mSet = [NSMutableSet set];
            [mSet addObject:@"英语"];
            [mSet addObject:@"历史"];
            [mSet addObject:@"数学"];
            
            NSArray *arr = @[@"a", @"b", @"c"];
            [mSet addObject:arr];
            
            NSMutableSet *subSet = mSet.mutableCopy;
            NSMutableSet *subSubSet = mSet.mutableCopy;
            [subSet addObject:subSubSet];
            [mSet addObject:subSet];
            
            NSDictionary *subDict = @{
                                      @"键0" : @"值0",
                                      @"键1" : @"值1",
                                      @"键2" : @"值2",
                                      };
            [mSet addObject:subDict];
            NSDictionary *dict = @{@"something" : mSet};
            
            NSLog(@"%@", dict);

        }

    }];
}

执行一次NSLog的时间:
系统的方法:0.582s / 1000
我的方法:0.893s / 1000

最后

Category以及Demo的Github地址:Demo

你可能感兴趣的:(解决NSLog字典,数组,集合时中文显示Unicode问题)