initialize方法
initialize与load的主要区别是在main函数之后调用,而load方法在main函数之前调用。initialize是系统自动调用的,重写时千万不要调用[super initialize],否则父类的initialize会被多次执行。当重写initialize方法的类第一次调用其方法时会调用initialize方法,或此类的子类首次调用方法时也会调用,当该类不使用时,该方法可能永远不会被调用。父类中的initialize方法调用肯定在子类之前。
即使类文件被引入到项目中,但没有被使用过,initialize方法是不会调用的。假如这个类放到代码中,而这段代码并没有被执行,这个函数是不会被执行的。
特点
定义父类
@interface AClass : NSObject
@end
@implementation AClass
+ (void)initialize{
NSLog(@"%s",__FUNCTION__);
}
@end
-
** initialize方法在main函数之后调用**
图一
-
父类的initialize比子类的initialize先执行
定义继承AClass的子类,并实现initialize方法
@interface SubClass : AClass
@end
@implementation SubClass
+ (void)initialize{
NSLog(@"%s",__FUNCTION__);
}
@end
log输出结果:
![](https://img.haomeiwen.com/i5809710/cd4368aa9fdcd108.png)
-
当子类中不实现initialize,会调用父类的initialize方法,在此之前,父类的方法会被优先调用一次
定义继承AClass的子类,不实现initialize方法
@interface SubClass : AClass
@end
@implementation SubClass
@end
log输出结果:
![](https://img.haomeiwen.com/i5809710/7adc568c82fa3ed7.png)
注:结合图一和图二可以看出,如果子类实现initialize,那么子类的initialize方法会替换父类的方法
-
当有多个Category都实现了initialize方法,会覆盖类中的方法,只执行一个
注意:执行顺序是按照Compile Sources 列表中最后一个Category 的initialize方法
定义多个AClass的Category,并且每个Category都实现initialize方法:
图四
查看Compile Sources中的.m文件顺序:
图五
此时的log打印情况:
图六
可以看到,当存在多个Category时,也只执行一个,具体执行哪一个Category中的initialize方法,测试后便可发现,会执行Compile Sources 列表中最后一个Category 的initialize方法
总结
initialize方法主要用来对一些不方便在编译期初始化的对象进行赋值,例如某些依赖runtime消息发送的实例,无法在编译时初始化。
- load和initialize的共同点
如果父类和子类都实现了,那么父类中的方法执行肯定在子类之前; - 当执行initialize时,程序的运行环境时基本健全的;
- initialize是线程安全的,内部使用了锁,需要注意避免阻塞线程;
网友评论