一、description方法
Description方法包括类方法和对象方法。(NSObject类所包含)
(一)基本知识
-description(对象方法)
使用NSLog和@%输出某个对象时,会调用对象的description方法,并拿到返回值进行输出。
+description(类方法)
使用NSLog和@%输出某个对象时,会调用类对象的description方法,并拿到返回值进行输出,把整个对象一次性打印出来,打印对象使用%@。
使用@%打印对象如(“@%”,P)默认打印输出为<类名:内存地址>,虽然字符串也是对象,但字符串在使用@%打印时情况特殊。
那么应该怎么实现打印对象的所有属性呢?在类的实现中重写description方法。
(二)实现打印对象的所有属性
(三)区别
+description方法决定了类对象的输出结果,即类本身
-description方法决定了实例对象的输出结果,即Person创建的对象。
(四)打印相关补充
二、SEL
SEL:全称Selector 表示方法的存储位置。
方法在内存中是怎么存储的?
Person *p=[[Person alloc] init];
[p test];
寻找方法的过程:
(1)首先把test这个方法名包装成sel类型的数据;
(2)根据SEL数据找到对应的方法地址;
(3)根据方法地址调用相应的方法。
(4)注意:在这个操作过程中有缓存,第一次找的时候是一个一个的找,非常耗性能,之后再用到的时候就直接使用。
关于_cmd:每个方法的内部都有一个-cmd,代表着当前方法。
注意:SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去寻找对应的方法地址,找到方法地址后就可以调用方法。这些都是运行时特性,发消息就是发送SEL,然后根据SEL找到地址,调用方法。
1 #import2 3 @interface Person : NSObject 4 5 + (void)test; 6 7 - (void)test2; 8 9 10 - (void)test3:(NSString *)abc;11 12 @end13 14 15 16 17 #import "Person.h"18 19 @implementation Person20 + (void)test21 {22 NSLog(@"test-----");23 }24 25 - (void)test226 {27 // _cmd代表着当前方法28 29 NSString *str = NSStringFromSelector(_cmd);30 31 // 会引发死循环32 // [self performSelector:_cmd];33 34 NSLog(@"调用了test2方法-----%@", str);35 }36 37 - (void)test3:(NSString *)abc38 {39 NSLog(@"test3-----%@", abc);40 }41 @end42 43 44 45 46 47 /*48 SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址。找到方法地址就可以调用方法49 50 51 其实消息就是SEL52 */53 54 #import 55 #import "Person.h"56 57 int main()58 {59 Person *p = [[Person alloc] init];60 61 [p test2];62 63 // NSString *name = @"test2";64 //65 // SEL s = NSSelectorFromString(name);66 //67 // [p performSelector:s];68 69 70 // 间接调用test2方法71 //[p performSelector:@selector(test2)];72 73 //[p test3:@"123"];74 75 76 // SEL s = @selector(test3:);77 //78 // [p performSelector:s withObject:@"456"];79 80 //[p test2];81 82 // 1.把test2包装成SEL类型的数据83 // 2.根据SEL数据找到对应的方法地址84 // 3.根据方法地址调用对应的方法85 return 0;86 }