测试
类
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
@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 *p2 = ; } }
|
输出结果:
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的结果可以看出:
- +load方法是在 main 函数之前执行的(测试1)
- +load方法最多被调用一次(测试2-5)
+initialize
从测试1-5的结果可以看出:
- 类在接收第一个方法前,将调用+initialize方法,包括:自身初始化(测试2)、子类初始化但父类未被使用过(测试3)
- 理论上来说,类的+initialize方法只应该被调用一次(测试3+测试4)。但如果子类没有实现+initialize方法,那么父类的+initialize将被调用(测试5)
避免多次调用
如果一个子类没有实现 +initialize 方法,那么父类的实现是会被执行多次的(测试5)。
有时候,这可能是你想要的;但如果我们想确保自己的 +initialize 方法只执行一次,避免多次执行可能带来的副作用时,可以使用下面的代码来实现:
1 2 3 4 5
| + (void)initialize { if (self == [ClassName self]) { } }
|