类的本质
-
本质
- 类其实也是一个 对象, 这个对象会在这个类第一次被使用的时候创建, 一个类再内存中只有一份类对象
- 只要有了类对象, 将来就可以通过类对象来创建实例对象
- 实例对象中有一个
isa指针
, 指向创建自己的类对象 - 类对象中保存了当前对象所有的对象方法, 当给一个实例对象发送消息的时候, 会根据实例对象中的isa指针去对应的类对象中查找
- 如何获取类对象: [实例对象 class]/ [类名 class];
-
类对象的应用场景:
- 1用于创建实例对象
- 2用于调用类方法
类的启动过程
-
load
方法:- 只要程序启动就会将所有类的代码加载到内存中, 放到代码区
-
load
方法会在当前类被 加载到内存 的时候调用, 有且仅会 调用一次 - 如果存在继承关系, 会 先调用父类的load方法, 再调用子类的load方法
-
initialize
方法:- 当前类第一次被使用的时候就会调用(创建类对象的时候)
-
initialize
方法在整个程序的运行过程中只会被 调用一次, 无论使用多少次这个类都只会调用一次 -
initialize
用于对某一个类进行 一次性的初始化 -
initialize
和load
一样, 如果存在继承关系, 会 先调用父类的initialize, 再调用子类的initialize
SEL类型
三种用法
- 配合对象/类来 检查 对象/类中有没有实现某一个方法
SEL sel = @selector(setAge:);
Person *p = [Person new];
// 判断p对象中有没有实现-号开头的setAge:方法
// 如果P对象实现了setAge:方法那么就会返回YES
// 如果P对象没有实现setAge:方法那么就会返回NO
BOOL flag = [p respondsToSelector:sel];
NSLog(@"flag = %i", flag);
- 2.配合对象/类来 调用某一个SEL方法
SEL sel = @selector(demo);
Person *p = [Person new];
// 调用p对象中sel类型对应的方法
[p performSelector:sel];
SEL sel1 = @selector(signalWithNumber:);
// withObject: 需要传递的参数
// 注意: 如果通过performSelector调用有参数的方法, 那么参数必须是对象类型,
// 也就是说方法的形参必须接受的是一个对象, 因为withObject只能传递一个对象
[p performSelector:sel1 withObject:@"13838383438"];
SEL sel2 = @selector(setAge:);
[p performSelector:sel2 withObject:@(5)];
NSLog(@"age = %i", p.age);
// 注意:performSelector最多只能传递2个参数
SEL sel3 = @selector(sendMessageWithNumber:andContent:);
[p performSelector:sel3 withObject:@"138383438" withObject:@"abcdefg"];
- 3.配合对象 将SEL类型作为方法的形参
Car *c = [Car new];
SEL sel = @selector(run);
Person *p = [Person new];
[p makeObject:c andSel:sel];// 调用传入对象的指定方法, 此处是c的run方法
网友评论