iOS - +load 和 + initialize的区别

简介: iOS - +load 和 + initialize的区别

1. +load 和+initialize调用时机次数


声明类PersonPerson+Category

//
//  Person.m
//  LoadInitializeDemo
//
//  Created by Ternence on 2021/5/10.
//
#import "Person.h"
@implementation Person
+ (void)load {
    [super load];
    NSLog(@"\n Person +load \n ");
}
+ (void)initialize {
    [super initialize];
    NSLog(@"\n Person +initialize");
}
@end

//
//  Person+Category.m
//  LoadInitializeDemo
//
//  Created by Ternence on 2021/5/10.
//
#import "Person+Category.h"
@implementation Person (Category)
+ (void)load {
    [super load];
    NSLog(@"\n Person Category +load \n ");
}
+ (void)initialize {
    [super initialize];
    NSLog(@"\n Person Category +initialize \n ");
}
@end


不调用不引用不用该类创建实例对象,启动App。查看打印

2021-05-10 14:47:05.534059+0800 LoadInitializeDemo[37437:645704] 
 Person +load
 Person Category +load


在其它类创建一个Person实例:

- (void)viewDidLoad {
    [super viewDidLoad];
    Person *person1 = [[Person alloc] init];
    NSLog(@"person1 created");
    Person *person2 = [[Person alloc] init];
    NSLog(@"person2 created");
}


查看打印:

Person +load
 Person Category +load
 Person Category +initialize
 person1 created 
 person2 created


对比两次打印结果,我们可以得出结论:


  1. 创建该类后不创建实例,发现+load调用了,且在main函数之前调用,+initialize并未调用


  1. 首次创建该类的实例的时候+initialize调用了,之后再没有调用


  1. 类和分类的+load都会在main函数之前调用


  1. +load 和+initialize 都只调用一次


2. 父类子类调用 +load 和 +initialize的先后顺序


创建StudentStudent+Category 继承自Person,不引用不调用PersonStudent,查看代码打印

2021-05-10 15:23:45.758752+0800 LoadInitializeDemo[59531:714585] 
 Person +load
 Person Category +initialize
 Person Category +load
 Student +load
 Person Category +load
 Person Category +load
 Student Category +load


结论:


+load


  1. 先调用类的+load,后调用分类的+load
  2. 先调用父类+load,后调用子类的+load
  3. 按照编译顺序调用+load(先编译先调用)


+initialize


  1. 先初始化分类,后初始化子类
  2. 先调用父类,后调用子类


3. 总结


  1. load是runtime加载类、分类的时候调用(只会调用一次)


  1. initialize是类第一次接收到消息的时候调用, 每一个类只会initialize一次(如果子类没有实现initialize方法, 会调用父类的initialize方法, 所以父类的initialize方法可能会调用多次)


4. +load使用场景


Runtime Swizzing 方法时,应该在+load方法中调用,因为此方法在类编译后,main函数之前,切只调用依次


5. +load源码阅读


官方源码地址:objc4


调用顺序:查看objc-os.mm


  • _objc_init
  • load_images
  • prepare_load_methods
  • schedule_class_load
  • add_class_to_loadable_list
  • add_category_to_loadable_list
  • call_load_methods
  • call_class_loads
  • call_category_loads
  • load_method_t


6. +initialize源码阅读


调用顺序:


  • objc-msg-arm64.s
  • _objc_msgSend
  • objc-runtime-new.mm
  • class_getInstanceMethod
  • lookUpImpOrForward
  • __class_initialize
  • callInitialize
  • objc_msgSend


相关文章
|
3月前
|
安全 Android开发 数据安全/隐私保护
请说明鸿蒙操作系统与其他操作系统(如Android和iOS)的主要区别。
请说明鸿蒙操作系统与其他操作系统(如Android和iOS)的主要区别。
59 1
|
7月前
|
C语言 索引
09-iOS之load和initialize底层调用原理分析
09-iOS之load和initialize底层调用原理分析
58 0
|
2月前
|
Java 测试技术 API
安卓APP和iOS APP在测试上的区别是什么?
安卓APP和iOS APP在测试上的区别是什么?
|
3月前
|
安全 JavaScript 前端开发
IOS开发基础知识:介绍一下 Swift 和 Objective-C,它们之间有什么区别?
IOS开发基础知识:介绍一下 Swift 和 Objective-C,它们之间有什么区别?
67 0
|
8月前
|
Shell iOS开发
iOS 逆向编程(十)sh脚本(shell)编写与执行指令区别
iOS 逆向编程(十)sh脚本(shell)编写与执行指令区别
175 0
|
8月前
|
安全 小程序 iOS开发
iOS Odyssey 和 unc0ver 的区别
iOS Odyssey 和 unc0ver 的区别
416 0
|
iOS开发
iOS开发-Opaque、Alpha、Hidden区别
在UIView中,有段时间Alpha,Hidden用的比较多,Opaque是最近才了解的,感觉有些不好理解于是就将这三个属性做了区分: 属性: 1、Alpha(不透明度) 2、Hidden(隐藏) 3、Opaque(不透明的) 1、Alpha(不透明度)
387 0
navigationBar tintColor barTintColor 分别在iOS7和它之前的区别
navigationBar tintColor barTintColor 分别在iOS7和它之前的区别
215 0
|
安全 iOS开发
iOS中assign和weak修饰符的区别
iOS中assign和weak修饰符的区别
82 0
|
存储 机器学习/深度学习 缓存
iOS - 链表、数组区别及常见算法
iOS - 链表、数组区别及常见算法