在 NSObject 类中有两个非常特殊的类方法 +load 和 +initialize ,用于类的初始化.下面介绍下他们的调用时机和一些使用的场景。
Demo
int main(int argc, char * argv[]) {
@autoreleasepool {
NSLog(@" main func run");
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
//父类
@implementation TestViewController
+(void)load {
NSLog(@" TestViewController run load");
}
+(void) initialize {
NSLog(@"TestViewController run initialize ");
}
@end
//子类
@interface ChildViewController : TestViewController
@end
@implementation ChildViewController
+(void)load {
NSLog(@" ChildViewController run load");
}
+(void) initialize {
NSLog(@"ChildViewController run initialize ");
}
@end
+load
Demo加载顺序
TestViewController run load
ChildViewController run load
main func run
+load 加载时机
- 类的加载,调用时机是是类被加入的runtime的时候。测试发现,它在程序main函数之前执行之前加载。
- 父类的+load 会在之类加载之前加载。每个分类的+load加载是没有书序的。
- 只要工程里面有类,这个类不需要被包含或者使用+load方法都会被执行。
使用场景
- +load方法是线程安全的,它内部使用了锁.所以需要避免一些带锁额操作。
- 一般在这里实现一些类的方法替换。
+initialize
加载顺序
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[TestViewController new];
return YES;
}
// 结果为
TestViewController run load
ChildViewController run load
main func run
TestViewController run initialize
/*************************/
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[ChildViewController new];
return YES;
}
// 结果为
TestViewController run load
ChildViewController run load
main func run
TestViewController run initialize
ChildViewController run initialize
+initialize 加载时机
- 在类或它的子类收到第一条消息之前被调用的,这里所指的消息包括实例方法和类方法的调用。
- 如果一个子类没有实现 +initialize 方法,那么父类的实现是会被执行多次的。如果有多个类继承自同一个类,如果子类都实现了+initialize方法,那么父类的+initialize方法只会被执行一次。如果子类没有实现+initialize方法,这个时候会调用父类的+initialize方法,这导致了父类的+initialize方法被执行多次。
- 为了确保初始化方法在+initialize被执行一次,可以使用如下方法:
+ (void)initialize {
if (self == [ClassName self]) {
// ... do the initialization ...
}
}
@interface Child2ViewController : TestViewController
@end
@implementation Child2ViewController
+(void)load {
NSLog(@" Child2ViewController run load");
}
//+(void) initialize {
// NSLog(@"Child2ViewController run initialize ");
//}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
@end
[ChildViewController new];
[Child2ViewController new];
//执行结果为
TestViewController run load
Child2ViewController run load
ChildViewController run load
main func run
TestViewController run initialize
ChildViewController run initialize
TestViewController run initialize
使用场景
- 可以把一些需要懒加载的的初始化的方法存放到这边。