先附上代码,load 方法的代码 我就不附上,大家可以自己动手测试一下。
@interface XZPerson : NSObject
@end
#import "XZPerson.h"
@implementation XZPerson
+ (void)initialize{
NSLog(@"XZPerson-initialize");
}
@end
//
#import "XZPerson.h"
@interface XZPerson (Eat)
@end
#import "XZPerson+Eat.h"
@implementation XZPerson (Eat)
+ (void)initialize{
NSLog(@"XZPerson(Eat)-initialize");
}
@end
//
#import "XZPerson.h"
@interface XZPerson (Drink)
@end
@implementation XZPerson (Drink)
+ (void)initialize{
NSLog(@"XZPerson(Eat)-initialize");
}
@end
//
#import "XZPerson.h"
@interface XZStudent : XZPerson
@end
#import "XZStudent.h"
@implementation XZStudent
+ (void)initialize{
NSLog(@"XZStudent-initialize");
}
@end
//
#import "XZStudent.h"
@interface XZStudent (Test1)
@end
#import "XZStudent+Test1.h"
@implementation XZStudent (Test1)
+ (void)initialize{
NSLog(@"XZStudent(Test1)-initialize");
}
@end
//
#import "XZStudent.h"
@interface XZStudent (Test2)
@end
#import "XZStudent+Test2.h"
@implementation XZStudent (Test1)
+ (void)initialize{
NSLog(@"XZStudent(Test2)-initialize");
}
@end
结论如下:
一,+load 方法 会在runtime 加载类/分类时调用 在程序运行过程中只会调用一次。
- 先调用类的+ load ,按照编译顺序来,先编译先调用
- 在调用子类的+load 方法之前,会先调用父类的。
- 假如类有分类,会优先调用分类的+load
- + load的方法是根据方法地址直接调用,并不是经过objc_msgSend 函数调用的。
- 可以参考runtime的源码,objc-os.mm 中的_objc_init 方法中查看load_images等等
二,+initialize方法会在类第一次接收消息食调用
- 先调用父类的+initialize方法,在调用子类的,只会初始化一次
- 如果子类没有实现+initialize方法会优先调用父类的initialize方法,所以父类的initialize方法会被调用多次
- 如果分类调用了+initialize方法,那么它会覆盖本身的initialize方法
- 按照编译顺序,后编译的分类有先调用。
- +initialize是通过objc_msgSend调用的。