做一个猜想,当父类、父类的分类、子类 都写了同一个方法,那么在调用的时候会优先调用哪个方法呢?我们可以先写一个简单的demo
@implementation Person
+ (void)test {
NSLog(@"%@",self.class);
}
@end
然后是Person的分类
#import "Person+Test.h"
@implementation Person (Test)
+ (void)test {
NSLog(@"Test %@",self.class);
}
@end
然后是Person的子类Student
#import "Student.h"
@implementation Student
+ (void)test {
NSLog(@"Student %@",self.class);
}
@end
他们同时写了Test方法,看一下这样调用的执行结果
[Person test];
[Student test];
可以看到,Person调用的分类的方法,Student调用了自己重写的方法。
那么如果我们删掉Student自己重写的方法呢
这个时候,调用的就都是分类的方法了。
这个时候如果Person又有了一个分类呢
@implementation Person (Live)
+ (void)test {
NSLog(@"Live %@",self.class);
}
@end
发现运行结果依然是
为什么会有这样的结果呢?
这个需要从OC中的方法调用机制和category中方法的加载顺序说起。
首先,OC中一个类调用方法的顺序是,先在自己的类中查找,如果找不到,才会找到父类当中,这就解释了,只要Student类中有这个方法,那么就一定会执行Student类中的方法。
其次,OC的类方法加载是,会按照先类中的方法,后分类中的方法,添加进方法列表中。但是在读取的时候,会先调用后进入列表的方法(可以理解成栈),所以,如果一个类和分类中都有一个方法,会优先调用分类中的方法。
最后,如果有多个分类都写了同一个方法,那么根据方法的调用规则,会调用后加入列表的方法,但是多个分类哪个先加入呢,是按照这里来的:
这个图上,是Live分类在前边,所以添加方法的时候,是先将Live分类的方法加入方法列表,后将Test分类的方法加入方法列表,所以最终执行的时候,调用的是Test中的方法。
如果想执行Live中的方法,可以改变这里的顺序为
这样,执行的结果就是Live了