官方链接:
load: developer.apple.com/documentati…
initialize: developer.apple.com/documentati…
调用方式的区别
load:根据函数地址直接调用
initialize:通过消息发送调用。
调用时机的区别
load: The
loadmessage is sent to classes and categories that are both dynamically loaded and statically linked, but only if the newly loaded class or category implements a method that can respond.
当一个类或分类被加载和链接时,如果其实现了load函数,则以函数形式执行。
initialize: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. Superclasses receive this message before their subclasses.
当一个类(及其子类)第一次收到消息时,它会以消息形式执行initialize()。
调用方式的区别
load:
- A class’s
+loadmethod is called after all of its superclasses’+loadmethods.- A category
+loadmethod is called after the class’s own+loadmethod.
- 子类会先执行父类的
load函数,子类未实现则不调用。 - 分类会先执行类的
load函数,再执行全部分类的load函数。
initialize:
The superclass implementation may be called multiple times if subclasses do not implement
initialize()—the runtime will call the inherited implementation—or if subclasses explicitly call[super initialize]. If you want to protect yourself from being run multiple times, you can structure your implementation along these lines:+ (void)initialize { if (self == [ClassName self]) { // ... do the initialization ... } }
- 如果子类和父类都实现了
initialize(),则会先执行父类的,再执行子类的。 - 如果子类没有实现
initialize(),会执行父类的,父类的initialize()可能被执行多次。 - 分类实现的
initialize()会覆盖类的实现。
使用场景
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;
}
}
initialize:
- 主要用来对一些不方便在编译期初始化的对象进行赋值。
// In Person.m
// int类型可以在编译期赋值
static int someNumber = 0;
static NSMutableArray *someArray;
+ (void)initialize {
if (self == [Person class]) {
// 不方便编译期复制的对象在这里赋值
someArray = [[NSMutableArray alloc] init];
}
}