类在默写时候需要初始化操作以后才可以正常使用,在Object类中,绝大不跟类都继承子NSObject这个根类,这个类哟两个类方法用来实现初始化操作即+ (void)load
方法和+ (void)initialize
方法。
说一下这两个放法的作用于区别
-
两个方法的介绍
-
+(void)load
当包含类或分类的的程序在载入系统的时候其实这时候也就是在程序启动的时候,即在程序启动的时候就会调用该方法,且该程序只会调用一次。如果有类和分类,则会先调用类在调用其分类。
在所用子类调用该方法的时候回先执行超类的load
方法,如代码还依赖了其他程序的库,那程序库的相关load
方法也会先执行,然而根据给定的程序库,我们无法判断各个类的在如顺序,因此在某个类的load
方法调用其他类是不恰当不安全的。如下例.
-
#import "BSClassA.h"
@implementation BSClassA
+ (void)load {
BSClassA *objcet = [BSClassA New];
}
此方法,系统都不会调用,此时对应的是+ (instancetype)allocWithZone:(struct _NSZone *)zone
等方法,这些方法即使超类不实现,当前类也会实现。
-
load方法务必要实现的精简一些,即尽量减少所执行的操作,因为程序在执行该方法的时候回阻塞,如果里面包含繁杂的代码,程序在执行期间将可能短暂的无响应。不要在里面等待死锁,也不要调用可能会死锁的方法。即尽量别在该方法中执行操作。(好像说半天又些废话),确实在类加载之前执行任何任务都好像不太合理。那么其真正的用途或主要的用途获取就调试的时候是在分类中编写,用于判断分类是否已经载入系统。那么替代该方法的应该是下面要介绍的方法
+ initialize
。 -
+(void)initialize
initialize
和load
方法有一个相同点即一个类只会调用一次,该类在类首次使用的时候调用,如果该类在整个程序运行过程中都没有调用该类,那么该类的initialize
始终都不会调用。且该类会先调用其超类的该方法。如下
#import "BSClassA.h"
@implementation BSClassA
+ (void)initialize {
NSLog(@"%s",__FUNCTION__);
}
@end
#import "BSClassB.h"
@implementation BSClassB
+ (void)initialize {
NSLog(@"%s",__FUNCTION__);
}
@end
由于BSClassB
继承自BSClassA
,而initialize
又遵守继承规则,即BSClassB
在执行初始化的时候回先执行BSClassA
中的initialize
方法,所以和其他拥有继承特性的方法相同,在子类执行该方法的时候先判断弗雷是否已经载入系统如下
+ (void)initialize {
if ([BSClassB class]) {
NSLog(@"%s",__FUNCTION__);
}
}
这时候只会打印一次,即这样我们即可在所期望的额类载入系统的时候才会执行相关的初始化操作。
-
上面提到
load
方法中务必要保持精简,那initialize
中也是这样,即不要执行好使的任务。其原因有三- 在某个类初始化的时候必定是在某个线程中进行,而该线程是不确定的,所以可能是UI线程,如果是这样,就会导致阻塞,导致应用程序无法相应。
-
我们无法控制类的初始化时机,类在使用前必定要初始化,但程序不能依赖某特定的时间点,否则当运行期系统更新改变的时候,同时改变类的初始化方式,如果鸡舍某个类会在某个类
-
功能共同点与区别
-
共同点
- 都是类方法
- 这两个方法都只会调用一次
-
不同点
- 调用的时机不同,
load
实在程序载入即程序启动的时候调用而initialize
是在首次使用该类的时候调用。再者load
必须阻塞并等着所有类的load
方法都执行完。 - 调用的方式不同,
load
是程序启动的时候回主动的调用所有load
方法,而initialize方法是调用某个类的时候才会调用, - 如上面提起的
initialize
方法不管其超类是否实现该方法,该类都会实现该方法。而load
如果本类为实现该方法,无论其超类是否实现,本类都不实现该方法。
- 调用的时机不同,
-
-
总结
尽量少用这两个方法待补充...
网友评论