+(void)initialize
+(void)load
Apple的文档很清楚地说明了initialize和load的区别在于:load是只要类所在文件被引用就会被调用,而initialize是在类或者其子类的第一个方法被调用前调用。所以如果类没有被引用进项目,就不会有load调用;但即使类文件被引用进来,但是没有使用,那么initialize也不会被调用。
它们的相同点在于:方法只会被调用一次。(其实这是相对runtime来说的,后边会做进一步解释)。
文档也明确阐述了方法调用的顺序:父类(Superclass)的方法优先于子类(Subclass)的方法,类中的方法优先于类别(Category)中的方法。
//Father.m
+ (void)load {
NSLog(@"Father:%s %@", __FUNCTION__, [self class]);
}
+ (void)initialize {
NSLog(@"Father:%s %@", __FUNCTION__, [self class]);
}
//Son.m Class Son Extends Father
+ (void)load {
NSLog(@"Son:%s %@", __FUNCTION__, [self class]);
}
//Son+load.m
+ (void)load {
NSLog(@"Son+load:%s %@", __FUNCTION__, [self class]);
}
//Other.m
+ (void)load {
NSLog(@"Other:%s %@", __FUNCTION__, [self class]);
}
+ (void)initialize {
NSLog(@"Other:%s %@", __FUNCTION__, [self class]);
}
//Other+initialize.m
+ (void)initialize {
NSLog(@"Other+initialize:%s %@", __FUNCTION__, [self class]);
}
//main.m
int main(int argc, char * argv[]) {
NSLog(@"Main method start!");
return 0;
}
RUN出来的结果如下:
2017-03-03 10:35:15.979 Load+Initialize[3271:684594] Other+initialize:+[Other(initialize) initialize] Other
2017-03-03 10:35:16.017 Load+Initialize[3271:684594] Other:+[Other load] Other
2017-03-03 10:35:16.018 Load+Initialize[3271:684594] Father:+[Father initialize] Father
2017-03-03 10:35:16.018 Load+Initialize[3271:684594] Father:+[Father load] Father
2017-03-03 10:35:16.018 Load+Initialize[3271:684594] Father:+[Father initialize] Son
2017-03-03 10:35:16.018 Load+Initialize[3271:684594] Son:+[Son load] Son
2017-03-03 10:35:16.018 Load+Initialize[3271:684594] Son+load:+[Son(load) load] Son
2017-03-03 10:35:16.019 Load+Initialize[3271:684594] Main method start!
当类被加载到runtime的时候就会运行,也就是说是在main.m之前~会根据Compile Sources中的顺序来加载。
需要注意的是加载son+load的顺序
- son的父类是father,所以先加载[Father initialize]和[Father load]。
- 执行 son的initialize,但是son内没有实现这个方法,所以执行父类的initialize,但是结果为son
- 执行son+load的load方法
//输出当前方法名
__FUNCTION__ 是C++编译器的标识符
__LINE__ 执行代码的行数