iOS load 和 initialize 认知
最近项目不怎么忙,抽空看了一些博客和简书的文章,发现自己还是小菜鸡一只,平时很基础的东西认识却还是很浅,很浅,今天就来说说load 和 initialize这两个类方法,如果有哪些地方写的不对的,请各位大神见谅,并能给出指导性建议,感激不尽...写本篇文章的目的也只是想记录一下自己的学习路程,见谅...
1. load
-
什么时候调用?
当一个类或者分类添加到Objective-C RunTime中时调,也就是程一已启动就会调用load方法,在main函数调用之前
创建一个Person类继承自NSObject
int main(int argc, char * argv[]) {
@autoreleasepool {
NSLog(@"%s",__func__);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
#import "Person.h"
@implementation Person
+ (void)load
{
NSLog(@"Person -- %s",__func__);
}
@end
在控制器
- (void)viewDidLoad {
[super viewDidLoad];
Person *p = [Person new];
}
image.png
-
调用的先后顺序?
先加载父类的load方法,再加载子类的load方法,分类的load方法在自己类的load方法调用之后,也就是先调用本类的,再调用分类的load方法,还有一种就不赘述了,调用流程就是: 父类 - 子类 - 分类
官方文档
A class’s +load method is called after all of its superclasses’ +load methods
A category +load method is called after the class’s own +load method
创建一个类继承自Person
Boy.m文件
@implementation Boy
+ (void)load
{
NSLog(@"--%s",__func__);
}
@end
Person.m文件
@implementation Person
+ (void)load
{
NSLog(@"Person -- %s",__func__);
}
@end
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
Person *p = [Person new];
}
看下面的运行顺序:先调用Person,后调用的Person的子类
image.png
再创建一个类继承自Boy
@implementation Boy (subBoy)
+ (void)load{
NSLog(@"%s",__func__);
}
@end
看下面的运行顺序:先调用Person - 子类 -分类
image.png
再创建一个Person的分类
#import "Person+load.h"
@implementation Person (load)
+ (void)load
{
NSLog(@"%s",__func__);
}
@end
运行结果如下:父类-子类-分类
image.png
-
调用几次呢?
如果不是手动去调用的话,只会调用一次,在这就不演示了
2.initialize
-
何时被调用?
通过runtime第一次向类发送信息时调用,可以理解成懒加载吧,用到的时候才会去调用
The runtime sends initialize to each class in a program just before the class, or any class that inherits from it, is sent its first message from within the program
-
调用顺序
父类在子类之前收到这个消息,如果子类没有实现initialize,runtime会调用父类的initialize实现,或者子类调用[super initialize],父类的initialize会调用多次,分类的实现会覆盖本类的实现
Superclasses receive this message before their subclasses
创建Person类
#import "Person.h"
@implementation Person
+ (void)initialize
{
NSLog(@"Person -- %s",__func__);
}
@end
#import "Person+load.h"
@implementation Person (load)
+ (void)initialize
{
NSLog(@"%s",__func__);
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Person *p = [Person new];
}
运行发现,分类的initialize,覆盖了本类的initialize方法
image.png
验证 - 父类在子类之前收到这个消息,如果子类没有实现initialize,runtime会调用父类的initialize实现
@implementation Person
+ (void)initialize
{
NSLog(@"Person -- %s",__func__);
}
@end
创建Boy类继承自Person,没有实现initialize
@implementation Boy
@end
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Boy *boy = [Boy new];
}
image.png
验证 - 分类的initialize覆盖本类的initialize方法
@implementation Person (load)
+ (void)initialize
{
NSLog(@"%s",__func__);
}
@end
image.png
如果你想保护自己不被多次运行,你可以按照以下方式来构建你的实现:
If you want to protect yourself from being run multiple times, you can structure your implementation along these lines:
Listing 1
+ (void)initialize {
if (self == [Person self]) {
NSLog(@"%s",__func__);
}
}
子类
#import "Boy.h"
@implementation Boy
+ (void)initialize
{
[super initialize];
NSLog(@"%s",__func__);
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Boy *boy = [Boy new];
}
image.png
如果改一下
#import "Person.h"
@implementation Person
+ (void)initialize {
// if (self == [Person self]) {
NSLog(@"%s",__func__);
// }
}
@end
image.png
差不多就这些内容,如果各位有需要补充的可以call我,共同进步吧!