iOSload和initialize
load和initialize详解
在介绍之前,我们首先来了解一下类的使用,我们要使用一个类,大概要经过以下步骤
1启动App,程序开始加载类到内存中(代码区) (void)load
2首次使用该类时,创建类对象(我们可以把它看作是一个单例,它在整个程序中只有一份) (void)initialize
3通过类对象创建实例对象 (instancetype)alloc、-(instancetype)init
4通过实例对象,我们就可使用实例方法、类属性了
从上面的步骤我们也大概了解到load和initialize的调用时机了,下面在来详细说一下
一、 load类方法
当类被引用进项目的时候就会执行load函数(在main函数开始执行之前),与这个类是否被用到无关,每个类的load函数只会自动调用一次.由于load函数是系统自动加载的,因此不需要再调用[super load],否则父类的load函数会多次执行。
●1.当父类和子类都实现load函数时,父类的load方法执行顺序要优先于子类
●2.当一个类未实现load方法时,不会调用父类load方法
●3.类中的load方法执行顺序要优先于类别(Category)
●4.当有多个类别(Category)都实现了load方法,这几个load方法都会执行,但执行顺序不确定(其执行顺序与类别在Compile Sources中出现的顺序一致)
●5.当然当有多个不同的类的时候,每个类load 执行顺序与其在Compile Sources出现的顺序一致
二、 initialize类方法
●即使类文件被引用进项目,但是没有使用,initialize不会被调用
●假如这个类放到代码中,而这段代码并没有被执行,这个函数是不会被执行的。
●类或者其子类的第一个方法被调用前调用
●由于是系统自动调用,也不需要再调用 [super initialize],否则父类的initialize会被多次执行
●父类的initialize方法会比子类先执行
●子类未实现initialize方法时,会调用父类initialize方法,子类实现initialize方法时,会覆盖父类initialize方法.
●当有多个Category都实现了initialize方法,会覆盖类中的方法,只执行一个(会执行Compile Sources 列表中最后一个Category 的initialize方法)
三、两者的异同
1、相同点
1load和initialize会被自动调用,不能手动调用它们。
2如果父类和子类都被调用,父类的调用一定在子类之前
3子类实现了load和initialize的话,会隐式调用父类的load和initialize方法。
4load和initialize方法内部使用了锁,因此它们是线程安全的。
2、不同点
1调用顺序不同,以main函数为分界, load方法在main函数之前执行, initialize在main函数之后执行。
2子类中没有实现 load方法的话,不会调用父类的 load方法;而子类如果没有实现 initialize方法的话,也会自动调用父类的 initialize方法。
3 load方法是在类被装在进来的时候就会调用, initialize在第一次给某个类发送消息时调用(比如实例化一个对象),并且只会调用一次,是懒加载模式,如果这个类一直没有使用,就不会调用到 initialize方法。
四、使用场景
1. load一般是用来交换方法Method Swizzle,由于它是线程安全的,而且一定会调用且只会调用一次,通常在使用UrlRouter的时候注册类的时候也在 load方法中注册。
(void)load {
static dispatch_once_t oneToken;
dispatch_once(&oneToken, ^{
Method imageNamed = class_getClassMethod(self,@selector(imageNamed:));
Method mkeImageNamed =class_getClassMethod(self,@selector(swizze_imageNamed:));
method_exchangeImplementations(imageNamed, mkeImageNamed);
});
}
(instancetype)swizze_imageNamed:(NSString*)name {
//这个时候swizze_imageNamed已经和imageNamed交换imp,所以当你在调用swizze_imageNamed时候其实就是调用imageNamed
UIImage * image;
if( IS_IPHONE ){
// iphone处理
UIImage * image = [self swizze_imageNamed:name];
if (image != nil) {
return image;
} else {
return nil;
}
} else {
// ipad处理,_ipad是自己定义,~ipad是系统自己自定义。
UIImage *image = [self swizze_imageNamed:[NSString stringWithFormat:@"%@_ipad",name]];
if (image != nil) {
return image;
}else {
image = [self swizze_imageNamed:name];
return image;
}
}
2. initialize方法主要用来对一些不方便在编译期初始化的对象进行赋值,或者说对一些静态常量进行初始化操作。
/ In Person.m
// int类型可以在编译期赋值
static int someNumber = 0;
static NSMutableArray *someArray;
(void)initialize {
if (self == [Person class]) {
// 不方便编译期复制的对象在这里赋值
someArray = [[NSMutableArray alloc] init];
}
}
五、总结
1load和initialize方法都会在实例化对象之前调用
2load执行在main函数以前,initialize执行main函数之后
3这两个方法会被自动调用,不能手动调用它们。
4load和initialize方法都不用显示的调用父类的方法而是自动调用
5子类没有initialize方法也会调用父类的方法,而load方法则不会调用父类
6initialize方法对一个类而言只会调用一次(Person、或者是Person Category)都是一个Perosn类。load方法则是每个都会调用,只要你写了load方法,添加到工程都会实现。
7load方法通常用来进行Method Swizzle,initialize方法一般用于初始化全局变量或静态变量。
8load和initialize方法内部使用了锁,因此它们是线程安全的。实现时要尽可能保持简单,避免阻塞线程,不要再使用锁。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgaibfb
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13