iOS - description 用于打印出便于查看的log

今天在研究代码的时候,发现一个很有趣的函数,- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level 便研究了一下。

个人博客: https://linit.space

问题

比如我们有如下代码块

    TestObj *object = [[TestObj alloc] init];
    object.name1 = @"vname1";
    object.name2 = @"vname2";
    object.name3 = @"vname3";
    object.name4 = @"vname4";
      NSLog(@"%@",@[@"1",@"2",@{@"keyxx":@"value",@"key2":@"value2",@"key3":@{@"1":@"xxxx",@"dic":@{@"你好啊1":@"林某某!",@"你好啊2":@"林某某!",@"你好啊3":@"林某某!",@"你好啊4":@"林某某!",@"你好啊5":@"林某某!",@"你好啊6":@"林某某!",@"你好啊7":@"林某某!"},@"axaasx":@"3"},@"key4":@"value4"},@"3",object]);

打印的结果是

(
    1,
    2,
        {
        key2 = value2;
        key3 =         {
            1 = xxxx;
            axaasx = 3;
            dic =             {
                "\U4f60\U597d\U554a1" = "\U6797\U67d0\U67d0\Uff01";
                "\U4f60\U597d\U554a2" = "\U6797\U67d0\U67d0\Uff01";
                "\U4f60\U597d\U554a3" = "\U6797\U67d0\U67d0\Uff01";
                "\U4f60\U597d\U554a4" = "\U6797\U67d0\U67d0\Uff01";
                "\U4f60\U597d\U554a5" = "\U6797\U67d0\U67d0\Uff01";
                "\U4f60\U597d\U554a6" = "\U6797\U67d0\U67d0\Uff01";
                "\U4f60\U597d\U554a7" = "\U6797\U67d0\U67d0\Uff01";
            };
        };
        key4 = value4;
        keyxx = value;
    },
    3,
    "<TestObj: 0x7fb7fbc71520>"
)

中文直接用unicode编码打印出,自定义类的内容也不明确,导致查看的非常的不方便。

解决方案

实现description开头方法,为了更加使得打印结果更有格式,所以实现- (NSString )descriptionWithLocale:(id)locale indent:(NSUInteger)level。
==
*注:优先级 - (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level > - (NSString *)description ,所以,例如NSDictionary,NSArray等,已经实现了- (NSString )descriptionWithLocale:(id)locale indent:(NSUInteger)level此方法,所以如果实现- (NSString )description则没有效果。==

原理

在使用NSObject类替换%@占位符时,会调用description相关方法,所以只要实现此方法,就可以起到修改打印内容的作用。因此对于系统的类,才用增加分类的方式实现,而自己的类,就是增加方法。

代码实现

#import <objc/runtime.h>
@interface TestObj : NSObject
@property (nonatomic, copy)NSString *name1;
@property (nonatomic, copy)NSString *name2;
@property (nonatomic, copy)NSString *name3;
@property (nonatomic, copy)NSString *name4;
@end

@implementation TestObj

- (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 appendFormat:@"<%@ = {\n",NSStringFromClass(self.class)];
    
    unsigned int outCount;
    objc_property_t *properties = class_copyPropertyList([self class], &outCount);
    for (int i = 0; i < outCount; i++)
    {
        objc_property_t property = properties[i];
        const char *charProperty = property_getName(property);
        NSString *propertyName = [NSString stringWithUTF8String:charProperty];
        if (propertyName) {
            id propertyValue = [self valueForKey:propertyName];
            NSString *lastSymbol = (outCount == i + 1) ? @"":@";";
            if ([propertyValue respondsToSelector:@selector(descriptionWithLocale:indent:)]) {
                [mStr appendFormat:@"\t%@%@ = %@%@\n",tab,propertyName,[propertyValue descriptionWithLocale:locale indent:level + 1],lastSymbol];
            } else {
                [mStr appendFormat:@"\t%@%@ = %@%@\n",tab,propertyName,propertyValue,lastSymbol];
            }
        }
    }
    free(properties);
    [mStr appendFormat:@"%@}>",tab];
    return mStr;
}

@end

@implementation NSDictionary (myTest)


- (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 (myTest)

- (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

结果

(
    1,
    2,
    {
        keyxx = value;
        key3 = {
            1 = xxxx;
            dic = {
                你好啊2 = 林某某!;
                你好啊6 = 林某某!;
                你好啊3 = 林某某!;
                你好啊7 = 林某某!;
                你好啊4 = 林某某!;
                你好啊1 = 林某某!;
                你好啊5 = 林某某!
            };
            axaasx = 3
        };
        key4 = value4;
        key2 = value2
    },
    3,
    <TestObj = {
        name1 = vname1;
        name2 = vname2;
        name3 = vname3;
        name4 = vname4
    }>
)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容