美文网首页otherSOC进化ios
#iOS 打印中文字典,数组,控制台输出中文,并保持缩进格式

#iOS 打印中文字典,数组,控制台输出中文,并保持缩进格式

作者: youngyunxing | 来源:发表于2016-11-13 23:02 被阅读2300次

    为了方便调试我们经常需要在控制台打印数组/字典信息,但是如果含有中文,打印出来的就是一堆看不懂的信息(其实是Unicode编码),影响开发效率.
    本文目标:

    • 使用NSLog能打印中文字典/数组
    • 在控制台使用 po 命令 显示的调试信息也是中文的

    2016-12-2 更新

    • 支持对控件的打印,比如view.subviews
    • 运用的是方法交换,只是对系统的debugDescription方法做转码处理,因此格式保留为系统风格
    • 只在DEBUG模式下有效,对线上版本无干扰

    效果:

    用NSLog打印效果用NSLog打印效果 控制台使用po命令效果控制台使用po命令效果

    如何使用

    直接拖进项目中去即可.非常简单.

    解决NSLog打印中文问题

    对于NSLog能打印中文字典/数组这个问题,首先看看网上的普通做法: 就是重新写一个字典和数组的分类,重写他们的- (NSString *)descriptionWithLocale:(id)locale这个方法
    代码如下:

    @implementation NSDictionary (Log)  
    - (NSString *)descriptionWithLocale:(id)locale  
    {  
        NSMutableString *string = [NSMutableString string];  
          
        // 开头有个{  
        [string appendString:@"{\n"];  
          
        // 遍历所有的键值对  
        [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOLBOOL *stop) {  
            [string appendFormat:@"\t%@", key];  
            [string appendString:@" : "];  
            [string appendFormat:@"%@,\n", obj];  
        }];  
          
        // 结尾有个}  
        [string appendString:@"}"];  
          
        // 查找最后一个逗号  
        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];  
          
        // 开头有个[  
        [string appendString:@"[\n"];  
          
        // 遍历所有的元素  
        [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOLBOOL *stop) {  
            [string appendFormat:@"\t%@,\n", obj];  
        }];  
          
        // 结尾有个]  
        [string appendString:@"]"];  
          
        // 查找最后一个逗号  
        NSRange range = [string rangeOfString:@"," options:NSBackwardsSearch];  
        if (range.location != NSNotFound)  
        [string deleteCharactersInRange:range];  
          
        return string;  
    }  性能呢
      
    @end  
    
    ```
    这样做可以解决问题,但是存在个问题:
    * 打印出来的格式不规范,看起来别扭,括号,大括号位置基本没法对上.
    
    说说我的思路:基本上和上面的一致,需要重写`- (NSString *)descriptionWithLocale:(id)locale`这个方法,不同的是,直接调用`self的description`方法,然后对返回的字符串进行处理,将其转换为中文.
    代码如下:
    给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就能打印出规范的中文了,效果如下:
    
    ![Paste_Image.png](http:https://img.haomeiwen.com/i1666610/d20ac35500d0fca3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    ####解决控制台调试命令`po`出来的不是中文问题:
    方案和上面的基本差不多,能用系统的方法就用系统的,毕竟系统的稳定,速度快.
    原理:使用'po'命令会调用`debugDescription`这个方法,这个返回调试环境下的信息,不建议重写`description`这个方法.
    代码如下:
    
    ```
    - (NSString *)descriptionWithLocale:(id)locale{
        return self.description.unicodeString;
    }
    - (NSString *)debugDescription{
        return self.description.unicodeString;
    }
    
    ```
    到此,使用`po`命令就可以查看包含中文的信息了.
    
    ![Paste_Image.png](http:https://img.haomeiwen.com/i1666610/18505aeae078ea48.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    附上最终github链接直接拖到项目中即可使用:<https://github.com/iOSSinger/CNLog>

    相关文章

      网友评论

      • 谦言忘语:想问下,文章的代码是直接重写方法,可是为什么github上是需要用到方法交换的呢?有什么好处吗?
      • BlueBar:崩了
      • 一场大雨:不错不错,很好,格式没改变,只是显示了汉字
        温柔vs先生:打印nslog为啥不是汉字
      • 一行代码一个世界:拖入文件是叫导入头文件:#import<objc/runtime.h>,不然会报错
        LWide:打印nslog为啥不是汉字 只有调试时可以
        一行代码一个世界:@iOSSinger 我也是用楼主的demo是出现的问题,在网上查的,为后来人节约时间
        youngyunxing:@一行代码一个世界 sorry,个人疏忽

      本文标题:#iOS 打印中文字典,数组,控制台输出中文,并保持缩进格式

      本文链接:https://www.haomeiwen.com/subject/oupcpttx.html