前言 在代码调试阶段,会不断的想查看想要检查的对象的各种属性信息,所以会经常会用到NSLog(<#NSString * _Nonnull format, …#>);系列的打印方式, 但是面对自定义的类,比如一个模型数组,打印出来确是一组< 类名:地址 >的信息。这部分信息对于检查类中的属性而言,是远远不够的。
NSLog(@"%@",classObject);
其实在构建需要打印到日志的字符串时,classObject会调用消息description,将description返回的字符串信息打印出来。
一:查看系统默认的打印信息格式
首先查看一下系统对常见的数据打印出来的信息格式
1、数组
NSArray * array = @[@"1",@"two",@3];
NSLog(@"array=>%@",array);
------输出信息------
array=>(
1,
two,
3
)
2、字典
NSDictionary *dict = @{@"title":@"description",
@"name" :@"name_dict"
};
NSLog(@"dict=>%@",dict);
------输出信息------
dict=>{
name = "name_dict";
title = description;
}
3、UI控件
UIView *view = [[UIView alloc]init];
NSLog(@"view=>%@",view);
------输出信息------
view=><UIView: 0x7fa53c509560; frame = (0 0; 0 0); layer = <CALayer: 0x600001eb6d80>>
4、基类NSObject
NSObject *object = [NSObject new];
NSLog(@"object=>%@",object);
------输出信息------
object=><NSObject: 0x600001cb4450>
显然<NSObject: 0x600001cb4450>这个打印信息和其他的相比显得过于精简了,当自定义继承自NSObject的类时,自定义的类的打印信息,依然后<Class: 地址>这种类型,想拿到自定义类中的舒心信息,需要在NSLog中手动控制去打印,如果多个地方使用并打印的话,会很麻烦。如果想NSLog(@“object=>%@”,object);时直接在打印信息中打印出自定义的类的需要查看的属性,那么只需要重写自定义类的description方式即可
二、重写自定义类的description方法
1、自定义一个Dog类:
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface DOVEDog : NSObject
/// 姓名
@property (nonatomic, copy) NSString * name;
/// 昵称
@property (nonatomic, copy) NSString * nickName;
/// 年龄
@property (nonatomic, assign) int age;
-(instancetype)initWithName:(NSString *)name
nickName:(NSString *)nickName
age:(int)age;
@end
NS_ASSUME_NONNULL_END
#import "DOVEDog.h"
@implementation DOVEDog
-(instancetype)initWithName:(NSString *)name nickName:(NSString *)nickName age:(int)age{
if (self = [super init]) {
_name = [name copy];
_nickName = [nickName copy];
_age = age;
}
return self;
}
@end
2、 重写其description方法:
-(NSString *)description{
return [NSString stringWithFormat:@"<%@:%p,%@,%@,%d>",[self class], self, _name, _nickName, _age];
}
查看类对象的输出信息:
DOVEDog *dog = [[DOVEDog alloc]initWithName:@"旺财" nickName:@"阿黄" age:1];
NSLog(@"%@",dog);
------输出信息------
<DOVEDog:0x600001eb6f40,旺财,阿黄,1>
- 该方式重写description方法后,在地址后面的属性信息的输出打印上看,其类似与NSArray,是没有规律而言的,但是不能否认,各个属性已经打印出来了。但是当属性特别的多时,我们仅从打印的一堆信息中,无法判断某事数据对应的属性是什么。
所以利用字典对象,将要输出打印的信息以字典的格式存起来,在教给%@
3、将要打印的属性交给字典管理,再由字典交给format输出
-(NSString *)description{
return [NSString stringWithFormat:@"<%@, %p,%@>",
[self class],
self,
@{
@"name":_name,
@"nickName":_nickName,
@"age":@(_age)
}];
}
查看打印信息
<DOVEDog, 0x6000011849c0,{
age = 1;
name = "\U65fa\U8d22";
nickName = "\U963f\U9ec4";
}>
利用字典的形式输出打印的好处:
- 知道每条数组的属性信息
- 可以为每条实例变量预留位置,使代码维护简单
- 增减属性的话,只要增减字典中的键值对即可
debugDescription
debugDescription方法是在调试器(debugger)中通过命令打印时调用的
如图所示,断点之后在调试控制台中输入lldb的po命令即可打印dog类对象的信息,在 (lldb) po dog后面的就是debugDescription返回的信息,可以利用debugDescription和description的区别,让对象在不同的场合下打印出来的信息不同。
重写debugDescription方法
-(NSString *)description{
return [NSString stringWithFormat:@"<%@, %p,%@>",
[self class],
self,
@{
@"name":_name,
@"nickName":_nickName,
@"age":@(_age)
}];
}
-(NSString *)debugDescription{
return [NSString stringWithFormat:@"在这里将输出Dog的属性数据,但是不现实Dog类对象的类名和地址<%@>",
@{
@"name":_name,
@"nickName":_nickName,
@"age":@(_age)
}];
}
查看输出打印信息:
故:
利用重写description输出更多有效信息
利用description和debugDescription的区别分别输出不同的信息