iOS 关于log输出

2017-05-07  本文已影响0人  莫太极

一个常用的宏

#ifdef DEBUG
#define CustomLog(FORMAT, ...)    do {\
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];\
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];\
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];\
[dateFormatter setDateFormat:@"HH:mm:ss:SSSS"];\
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];\
fprintf(stderr,"[%s:%d %s] %s\n", [[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [dateString UTF8String], [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);\
}  while (0)
#else
#define CustomLog(FORMAT, ...) nil
#endif

Q: do { ...} while(0) 是什么鬼,tell me why?
A: 当然是执行一次了,完美(😝开个玩笑)其实我以前用的就是不加do { ...} while(0) 感觉all in control
有一天看到了一篇文章提到下面这样写会报错

if (1)
       CustomLog(@"%@",Fuck);
   else{
     
   }

原因很简单。当编译时宏替换后代码就变成这样了

if (1)
        {\
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];\
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];\
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];\
[dateFormatter setDateFormat:@"HH:mm:ss:SSSS"];\
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];\
fprintf(stderr,"[%s:%d %s] %s\n", [[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [dateString UTF8String], [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);\
}) ; 
    else{
      
    }

简单点

 if (1){
        NSLog(@"1");
    };
    else{

    }

因为多出来的那个分号,会报错。So,为了严谨还是加do while
个人感觉这种情况很少见,一般人为了代码的可读性都不会省略花括号的,就算省略了也不会写这么一句log吧(砖友们在下眼界有限,尽管来喷)


再说descrription

调试程序时,经常需要打印查看对象信息,比如这样:

NSLog (@"object = %@", object);

然而,在自定义的类上这么做,那么输出的信息却是下面这样:

<WGPerson: 0x600000005bb0>

上面的内容明显满足不了我们的渴求,只有类名和地址,而强大的我们需求的应该更多(🤓)

要想输出更为爽快的也简单,只需覆写description方法。例如,下面这个代表个人信息的类:

#import <Foundation/Foundation.h>

@interface WGPerson : NSObject

@property(nonatomic,copy,readonly)NSString *personName;

@property(nonatomic,assign,readonly)NSUInteger personAge;

- (id)initWithPersonName:(NSString *)name
                     Age:(NSUInteger )age;

@end


@implementation WGPerson

-(id)initWithPersonName:(NSString *)name
                    Age:(NSUInteger)age
{
    if ((self = [super init])) {
        _personName = [name copy];
        _personAge  =  age;
    }
    return self;
}

- (NSString *)description{
    return [NSString stringWithFormat:@"<%@: %p, name:%@, age:%zd>",[self class], self, _personName, _personAge]; 
}

@end

输出就会变成这样

WGPerson *person =[[WGPerson alloc]initWithPersonName:@"Lily" Age:18];
NSLog(@"%@",person);
//<WGPerson: 0x600000032800, name:Lily, age:18>

但是,一旦属性很多这样写就有点坏味道了,我们通常在description方法中,把待打印的信息放到字典里面

- (NSString *)description{
    return [NSString stringWithFormat:@"<%@: %p, %@>",
            [self class],
            self,
            @{
              @"personName":_personName,
              @"personAge":@(_personAge)
              }];
}

用NSDictionary来实现此功能可以令代码更容易维护:如果以后还要向类中新增属性,并且要在description方法中打印,那么只需要修改字典内容即可。

还有debugDescription

与description非常相似。区别在于,debugDescription是开发者在调试器中一控制台命令打印对象时才调用的。在NSObject类的默认实现中,此方法只是直接调用了description
也就是说,当你只覆写了description,此时NSLog的输出与你在lldb中po的是一样的
也许你只是想把某些属性放在Person对象的普通描述信息中,更详尽的内容放在调试的描述信息里,此时可用下列代码实现:


- (NSString *)description{
    return [NSString stringWithFormat:@"<%@: %p, %@>",
            [self class],
            self,
            @{
              @"personName":_personName,
              }];
}

-(NSString *)debugDescription{
    return [NSString stringWithFormat:@"<%@: %p, %@>",
            [self class],
            self,
            @{
              @"personName":_personName,
              @"personAge":@(_personAge)
              }];
    
}

输出结果如下:

<WGPerson: 0x600000034100, {
    personName = Lily;
}>
(lldb) po person
<WGPerson: 0x600000034100, {
    personAge = 18;
    personName = Lily;
}>

再插一嘴,如果你的控制台打印酱婶

(lldb) po person
error: Couldn't materialize: couldn't get the value of variable person: no location, value may have been optimized out
error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression

你应该是在release模式。别问我咋知道的

上一篇 下一篇

猜你喜欢

热点阅读