测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@interface Person : NSObject

+ (void)load {
NSLog(@"%s", __func__);
}

+ (void)initialize {
NSLog(@"%s", __func__);
}

@end

@interface Father : Person

+ (void)load {
NSLog(@"%s", __func__);
}

+ (void)initialize {
NSLog(@"%s", __func__);
}

@end

@interface Son : Person

//+ (void)load {
// NSLog(@"%s", __func__);
//}
//
//+ (void)initialize {
// NSLog(@"%s", __func__);
//}

@end

测试

测试1

1
2
3
4
5
int main(int argc, char * argv[]) {
@autoreleasepool {
NSLog(@"%s", __func__);
}
}

输出结果:

1
2
3
[20:27:39] +[Person load] [第14行] +[Person load]
[20:27:39] +[Father load] [第14行] +[Father load]
[20:28:09] main [第16行] main

测试2

1
2
3
4
5
6
7
8
int main(int argc, char * argv[]) {
@autoreleasepool {
NSLog(@"%s", __func__);

Person *p1 = [[Person alloc] init];
Person *p2 = [[Person alloc] init];
}
}

输出结果:

1
2
3
4
[20:27:39] +[Person load] [第14行] +[Person load]
[20:27:39] +[Father load] [第14行] +[Father load]
[20:30:35] main [第16行] main
[20:27:39] +[Person initialize] [第18行] +[Person initialize]

测试3

1
2
3
4
5
6
7
int main(int argc, char * argv[]) {
@autoreleasepool {
NSLog(@"%s", __func__);

Father *f = [[Father alloc] init];
}
}

输出结果:

1
2
3
4
5
[20:27:39] +[Person load] [第14行] +[Person load]
[20:27:39] +[Father load] [第14行] +[Father load]
[20:31:47] main [第16行] main
[20:27:39] +[Person initialize] [第18行] +[Person initialize]
[20:27:39] +[Father initialize] [第18行] +[Father initialize]

测试4

1
2
3
4
5
6
7
8
int main(int argc, char * argv[]) {
@autoreleasepool {
NSLog(@"%s", __func__);

Person *p = [[Person alloc] init];
Father *f = [[Father alloc] init];
}
}

与测试3一样的输出结果:

1
2
3
4
5
[20:27:39] +[Person load] [第14行] +[Person load]
[20:27:39] +[Father load] [第14行] +[Father load]
[20:31:47] main [第16行] main
[20:27:39] +[Person initialize] [第18行] +[Person initialize]
[20:27:39] +[Father initialize] [第18行] +[Father initialize]

测试5

1
2
3
4
5
6
7
8
int main(int argc, char * argv[]) {
@autoreleasepool {
NSLog(@"%s", __func__);

Person *p2 = [[Person alloc] init];
Son *s = [[Son alloc] init];
}
}

输出结果:

1
2
3
4
5
[20:27:39] +[Person load] [第14行] +[Person load]
[20:27:39] +[Father load] [第14行] +[Father load]
[20:35:30] main [第16行] main
[20:27:39] +[Person initialize] [第18行] +[Person initialize]
[20:27:39] +[Person initialize] [第18行] +[Person initialize]

+load

从测试1-5的结果可以看出:

  1. +load方法是在 main 函数之前执行的(测试1)
  2. +load方法最多被调用一次(测试2-5)

+initialize

从测试1-5的结果可以看出:

  1. 类在接收第一个方法前,将调用+initialize方法,包括:自身初始化(测试2)、子类初始化但父类未被使用过(测试3)
  2. 理论上来说,类的+initialize方法只应该被调用一次(测试3+测试4)。但如果子类没有实现+initialize方法,那么父类的+initialize将被调用(测试5)

避免多次调用

如果一个子类没有实现 +initialize 方法,那么父类的实现是会被执行多次的(测试5)。
有时候,这可能是你想要的;但如果我们想确保自己的 +initialize 方法只执行一次,避免多次执行可能带来的副作用时,可以使用下面的代码来实现:

1
2
3
4
5
+ (void)initialize {
if (self == [ClassName self]) {
// ... do the initialization ...
}
}