美文网首页
iOS 关于log输出

iOS 关于log输出

作者: 莫太极 | 来源:发表于2017-05-07 14:33 被阅读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
  • 它的作用精简系统的打印输出,省去了一大串没用的信息,比如年月日,项目名等等,让log更加清晰明了。

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模式。别问我咋知道的

相关文章

  • iOS 关于log输出

    一个常用的宏 它的作用精简系统的打印输出,省去了一大串没用的信息,比如年月日,项目名等等,让log更加清晰明了。 ...

  • iOS宏关闭NSLog输出

    Release版本关闭Log输出 输出更详细的调试信息 参考文章:iOS开发-使用宏自定义输出(NSLog)

  • 关于NSLog

    关于NSLog log 用来输出日志信息。所以 iOS 项目中中的NSLog 也是非常之多。你们项目中肯定有这种代...

  • console.log

    关于console.log 在控制台输出有样式 console.log('%c 你想输出的值', 'font-si...

  • APP开发实战128-APP Log功能设计

    31 Log功能设计 31.1Log输出控制 1 debug版本输出log,release版本不输出log A 通...

  • HTML学习小记六

    1.关于console.log()向web控制台输出调试内容:window.console.log();windo...

  • OC数组长度Count的符号与越界问题

    先看两个例子 会输出log吗 会输出log吗,会输出几次 答案第一个不会输出log,第二个会输出log,会打印非常...

  • iOS11适配

    1.在iOS11系统上跑不起来项目,log输出nw_proxy_resolver_create_parsed_ar...

  • 【iOS开发】iOS10 Log调试小工具

    【iOS开发】iOS10 Log调试小工具 【iOS开发】iOS10 Log调试小工具

  • CocoaLumberjack 日志分文件输出

    CocoaLumberjack 是 iOS 下强大的日志解决方案,项目开发中,需要将不同模块代码下的 Log 输出...

网友评论

      本文标题:iOS 关于log输出

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