一、调用时机
在类第一次接收到消息的时候调用
二、调用顺序
- 先调用父类的initialize方法,再调用子类的initialize方法(递归,每个类只会初始化一次)
- 如果子类没有实现initialize方法,则会调用父类的initialize方法(消息调用机制,通过superclass指针向上查找)(所以,父类的initialize方法可能会被调用多次)
- 如果分类实现了initialize方法,会“覆盖”类本身的initialize调用(方法合并的时候,分类的方法更靠前)
三、源码窥探
void initializeNonMetaClass(Class cls) {
ASSERT(!cls->isMetaClass());
Class supercls;
bool reallyInitialize = NO;
supercls = cls->superclass;
if (supercls && !supercls->isInitialized()) {
initializeNonMetaClass(supercls);
}
if (!cls->isInitialized() && !cls->isInitializing()) {
cls->setInitializing();
reallyInitialize = YES;
}
if (reallyInitialize) {
callInitialize(cls);
lockAndFinishInitializing(cls, supercls);
}
}
四、示例分析(一)
1. 结构图(均实现了initialize方法)
2. 代码
①:[Person class];
②:[Student class];
③:[GoodStudent class];
④:[NorStudent class];
+[Person initialize]
+[Student initialize]
+[GoodStudent initialize]
+[NorStudent initialize]
3. 分析
- 执行代码①,给Person发消息,Person的父类NBObjcet没有实现initialize方法,所以调用父类的方法,不会有打印信息,接着调用Person类中的initialize方法,打印+[Person initialize]
- 执行代码②,给Student发消息,先看父类Person是否初始化,因为父类已经初始化,所以调用Student类的initialize方法,打印+[Student initialize]
- 执行代码③,给GoodStudent发消息,先看父类Student是否初始化,代码执行逻辑同上
- 执行代码④,给NorStudent发消息,代码执行逻辑同上
4. 总结
- 先调用父类的initialize方法,再调用子类的initialize方法
- 每个类只会初始化一次
五、实例分析(二)
1. 结构图(部分实现了initialize方法)
2. 代码
①:[Person class];
②:[Student class];
③:[GoodStudent class];
④:[NorStudent class];
/// 调用结果
+[Person initialize]
+[Student initialize]
+[Student initialize]
+[NorStudent initialize]
3. 分析
4. 总结
- 如果子类没有实现initialize方法,则会调用父类的initialize方法
- 父类的initialize方法可能会被调用多次
|