iOS load方法与initialize方法

在 iOS 开发中,我们经常会使用 +load 方法来做一些在 main 函数之前的操作,比如方法交换(Method Swizzle)等。现在分析一下load方法跟initialize方法的调用顺序以及区别。

1.先看下load方法

尝试定义一个继承自 NSObject 的 Person 类,并对其添加两个分类 Life 和 Work;再定义一个 Student 类继承自 Person,并对其添加 School 分类。在以上所有类和分类中,均实现 +load:

#import "Person.h"

@implementation Person

+ (void)load {

NSLog(@"Person %s", __func__);

}

@end

#import "Person+Life.h"

@implementation Person (Life)

+ (void)load {

NSLog(@"Person+Life %s", __func__);

}

@end

#import "Person+Work.h"

@implementation Person (Work)

+ (void)load {

NSLog(@"Person+Work %s", __func__);

}

@end

#import "Student.h"

@implementation Student

+ (void)load {

//    [super load];

NSLog(@"Student %s", __func__);

}

@end

#import "Student+School.h"

@implementation Student (School)

+ (void)load {

NSLog(@"Student+School %s", __func__);

}

@end

启动项目,打印结果如下,说明 +load 方法会在 main 函数之前被调用;且调用顺序总是先父类再子类再分类

当我们在一个类的子类的 +load 中 [super load] 又会调用到到底哪个类中呢(当然,在实际开发中这种情几乎不可能存在)?答案就是 [super load] 将调用到 Person 最后一个被编译的分类(Person+Work)中的 +load 方法,因为这里是消息发送,而不是通过方法指针。

应用:因为类或者分类一旦被加载到运行时,就会调用这个方法;因为加载时间特别早:所以可以利用这个特性进行一些处理

2.之后分析 initialize方法

在person与student类中添加init方法跟initialize方法,然后在 ViewController 中创建 Person 和 student 对象,如下:

#import "Person.h"

@implementation Person

-(instancetype)init{

if (self = [super init]) {

NSLog(@"%s",__func__);

}

return self;

}

+ (void)load {

NSLog(@"Person %s", __func__);

}

+ (void)initialize{

NSLog(@"Person %s",__func__);

}

@end

#import "Student.h"

@implementation Student

-(instancetype)init{

if (self = [super init]) {

NSLog(@"%s",__func__);

}

return self;

}

+ (void)load {

NSLog(@"Student %s", __func__);

}

+ (void)initialize{

NSLog(@"Student %s",__func__);

}

@end


@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

NSLog(@"%s",__func__);

Person * per = [[Person alloc]init];

Student * stu = [[Student alloc]init];

// Do any additional setup after loading the view, typically from a nib.

}

启动项目,运行结果如下:

由此得出结论

  1. loadinitialize方法都会在实例化对象之前调用,以main函数为分水岭,前者在main函数之前调用,后者在之后调用。
  2. initialize方法的调用顺序是先父类再子类;是以懒加载的方式被调用的;

原文地址:https://www.cnblogs.com/cui-cui/p/11433780.html

时间: 2024-12-11 02:13:27

iOS load方法与initialize方法的相关文章

iOS开发-OC篇 load方法 和 initialize方法比较

Load方法 和 initialize方法的比较    在OC语言中,我们相比之下对于load和initialize方法的使用比较少,所以会不是很清楚的了解二者的用途和区别,所以整理了一下,和大家进行分享,有所得不对的地方,希望能够指出来,多谢! 1.load方法特点: 1> 当类被引用进程序的时候会执行这个函数 2> 一个类的load方法不用写明[super load],父类就会收到调用,并且在子类之前. 3> Category的load也会收到调用,但顺序上在主类的load调用之后.

黑马程序员-OC类的本质,深入探讨,load方法和initialize方法

1:类的本质:类也是一种类,可以叫做类类,类对象,类类型: 2:类和对象在内存中分配问题(注意区分类的对象和类对象的概念) 类对象在内存中只有一份,且只加载一次,类对象中存放了类中定义的方法: 而成员变量和isa指针,存放在了类的对象中;isa指针指向了类对象:如图: 3:类本身也是对象,是class类型的对象: // 以person为例 Person *p1 = [[Person alloc] init]; Person *p1 = [[Person alloc] init]; // 获取类对

iOS Load方法 和 initialize方法的比较

一.load方法特点: 1. 当类被引用进程序的时候会执行这个函数 2.一个类的load方法不用写明[super load],父类就会收到调用,并且在子类之前. 3.Category的load也会收到调用,但顺序上在主类的load调用之后. 二.initialize方法特点: 1. initialize的自然调用是在第一次主动使用当前类的时候 2.和load不同,即使子类不实现initialize方法,会把父类的实现继承过来调用一遍.注意的是在此之前,父类的方法已经被执行过一次了,同样不需要su

【OC底层】Category、+load方法、+initialize方法原理

Category原理 - Category编译之后的底层结构是 struct categroy_t,里面存储着分类对象方法.属性.协议信息- 当程序运行时,通过runtime动态的将分类的方法.属性.协议合并到一个大数组中- 底层使用的是二维数组进行存储,比如:[[分类2方法列表],[分类1方法列表],[原方法列表]]- 将合并后的分类数据(方法.属性.协议)的数组插入到类原来数据的前面,如上- 因为它遍历分类是按倒序遍历的,所有越后面参与编译的Category数据,会在数组的前面  源码的的

OC 中 load 方法和 initialize 方法的异同

+ (void)load; 当类对象被引入项目时, runtime 会向每一个类对象发送 load 消息 load 方法会在每一个类甚至分类被引入时仅调用一次,调用的顺序:父类优先于子类, 子类优先于分类 load 方法不会被类自动继承 + (void)initialize; 也是在第一次使用这个类的时候会调用这个方法

load和initialize方法

  一.load 方法什么时候调用: 在main方法还没执行的时候 就会 加载所有类,调用所有类的load方法. load方法是线程安全的,它使用了锁,我们应该避免线程阻塞在load方法. 在项目中使用的一些场景: 比如我们要统计所有页面(UIViewController.UITableViewController)的数据,可以在UIViewController的类别里的load方法里实现Method Swizzle @implementation UIViewController (BaseM

懒惰的 initialize 方法

因为 ObjC 的 runtime 只能在 Mac OS 下才能编译,所以文章中的代码都是在 Mac OS,也就是 x86_64 架构下运行的,对于在 arm64 中运行的代码会特别说明. 写在前面 这篇文章可能是对 Objective-C 源代码解析系列文章中最短的一篇了,在 Objective-C 中,我们总是会同时想到 load.initialize 这两个类方法.而这两个方法也经常在一起比较: 在上一篇介绍 load 方法的文章中,已经对 load 方法的调用时机.调用顺序进行了详细地分

iOS开发-类的加载load函数和initialize函数

简要概括 load是类加载方法,initialize是类初始化方法. 要点 不需要调用super的方法. initialize和load方法系统只调用一次,开发者可以多次调用(可以,但是不建议). 类加载到系统调用load方法,类首次使用调用initialize方法. initialize和load的方法不要添加太多逻辑,类比不要在初始化方法做太多操作. initialize中可以实现无法在编译期初始化的全局变量,load的方法中可以实现swizzling的逻辑. load的调用并不视为类的第一

iOS培训笔记--load,initialize方法

+(void)load:在程序启动时就会调用一次该方法特点:先调用父类,再调用子类,再调用分类(编译的时候加载顺序:父类->子类->分类),分类中的load不会覆盖主类中的load +(void)initialize:在类被头一次使用时会调用该方法特点:先调用父类中的initialize,再调用子类中的initialize