LGPerson
@interface LGPerson : NSObject
- (void)sayNB;
+ (void)sayHappay;
@end
@implementation LGPerson
- (void)sayNB{
NSLog(@"%s",__func__);
}
+ (void)sayHappay{
NSLog(@"%s",__func__);
}
@end
LGStudent
@interface LGStudent : LGPerson
- (void)sayHello;
- (void)sayMaster;
+ (void)sayObjc;
@end
@implementation LGStudent
- (void)sayHello{
NSLog(@"%s",__func__);
}
+ (void)sayObjc{
NSLog(@"%s",__func__);
}
@end
方法调用
LGStudent *student = [[LGStudent alloc] init];
// 对象方法
[student sayHello];
[student sayNB];
// [student sayMaster];
// 类方法
[LGStudent sayObjc];
[LGStudent sayHappay];
[LGStudent performSelector:@selector(sayEasy)];
1. [LGStudent sayHappay]
;方法调用时,因为LGStudent
中没有sayHappay
方法, 则向上查找sayHappay
方法, 父类LGPerson
实现, 则调用,打印为+[LGPerson sayHappay]
2. [LGStudent performSelector:@selector(sayEasy)];
调用时, 内部实际上使用runtime
进行的方法调用, 和 [LGStudent sayEasy]
是相同的, 不同的是在编译阶段
,编译器
不会报错, 这里因为LGStudent
和LGPerson
中都未实现sayEasy
方法, 则报错unrecognized selector
为了不改变两个类的结构, 我们可以使用分类来给类添加方法, 可以给LGStudent
和LGPerson
添加分类, 就不详细说了,这里我们使用给NSObject
来添加分类NSObject+LGCate
@interface NSObject (LGCate)
- (void)sayEasy;
@end
@implementation NSObject (LGCate)
- (void)sayEasy{
NSLog(@"%s",__func__);
}
这样添加方法, 调用会报错吗?
答案: 会报错
|
|
|
|再思考一会
|
|
我们运行看下结果
不会报错
并执行了NSObject中添加的分类方法
why?
类方法查找流程和父类继承关系是一致的.
LGStudent类方法 存储在元类(LGStudent)里面, 在元类里的形式为实例方法,
查找不到则向上 元类(LGStudent)
的父类元类LGPerson
里查找,
查找不到则向上 跟元类(LGPerson)
的父类根元类NSobject
里查找,
查找不到则向上 跟元类(LGPerson)
的父类NSobject
里查找,
分类中有方法实现则调用, 所以不会报错
我们可以在NSObject
中给任何子类
拓展方法,而且不用区分是否是实例方法
还是类方法