一.description:
默认情况下:
使用NSLog和%@打印 "对象":如(@“%@”,P)默认打印输出为<类名:内存地址>。
person *p = [[person alloc] init];
p.age = 18;
p.name = @"xxx";
NSLog(@"%@",p);//直接使用nslog和%@打印对象
流程:
- 会调用对象p的
-description
方法 - 拿到
-description
方法的返回值(NSString *)显示到控制台上 -description
方法默认返回的是“类名+内存地址”
那么应该怎么实现打印对象的所有属性呢?
在类中的实现中重写description方法。
对象方法(-description方法):
使用 NSLOg 和 %@ 输出某个对象时,会调用对象的-(descripation)方法,并拿到返回值进行输出.
类方法(+description方法) :
使用
NSLog
和%@
输出某个对象时,会调用类对象+description
方法,并拿到返回值进行输出。注意:
- 会调用类的 +description 方法
- 拿到 +description 方法的返回值(NSString *)显示到控制台上
- +description 方法默认返回的是“类名”
例子:
注意:
+description方法决定了类对象的输出结果,即类本身
-description方法决定了实例对象的输出结果,即Person创建的对象。
打印补充:
二.SEL:全称 Selector 表示方法存储位置
方法的存储在不同位置:
1.类方法存储在 元类中
2.对象方法存储在 类对象中
person *p = [Person alloc] init];
[p test];
寻找方法的过程:
(1)首先把test这个方法名包装成sel类型的数据;
(2)根据SEL数据找到对应的方法地址;
(3)根据方法地址调用相应的方法。
(4)注意:在这个操作过程中有缓存,第一次找的时候是一个一个的找,非常耗性能,之后再用到的时候就直接使用。
注意:每个方法内部都有一个_cmd,代表当前方法.
SEL 类型的定义:
typedef struct objc_selector *SEL;
SEL 对象的创建:
SEL s = @selector(test);
SEL s2 = NSSelectorFromString(@"test");
SEL 对象的调用:
// 将 SEL 对象转化为 NSString 对象
NSString *str = NSStringFromSelector(@selector(test));
Person *p = [Person new];
// 调用对象p的test方法
[p performSelector:@selector(test)];
//
[p performSelector:@selector(test2:) withObject:];
注意:
- (void)test2
{
// _cmd代表着当前方法
NSString *str = NSStringFromSelector(_cmd);
// 会引发死循环
// [self performSelector:_cmd];
NSLog(@"调用了test2方法-----%@", str);
}
注意:SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去寻找对应的方法地址,找到方法地址后就可以调用方法。这些都是运行时特性,发消息就是发送SEL,然后根据SEL找到地址,调用方法。