load and initialize - xiangwangfeng/xiangwangfeng.github.io GitHub Wiki

概述

+load + initialize
调用时机 被添加到 runtime 收到第一次消息
调用顺序 父类->子类->分类 父类->子类
调用次数 1 次 多次 (子类没实现会调用父类)
分类方法 都会被调用到 分类方法会覆盖,只有唯一的一个方法会被调用
显示调用 super 不需要 不需要

源码参考

参考源码 苹果官网源码

调用时机

+load: _objc_init() => load_images() => call_load_methods()

+initialize: lookUpImpOrForward()/storeWeak()/object_setClass()=>_class_initialize()

调用顺序

+load: 调用完所有类方法后,再调用分类方法,调用类方法时,先调用父类,再调用子类。

+initialize: 如果有父类,则获得父类 supercls,再调用 _class_initialize(supercls),核心方法为 callInitialize(cls)

调用顺序

+load: 核心方法 call_class_loads(),内部使用函数指针直接调用,保证只调用一次

+initialize: 核心方法 callInitialize(),内部实现为 objc_msgSend。所以如果子类没有实现 initialize ,则在子类的 callInitialize() 方法中实际上是调用父类方法。这种场景将导致父类方法被调用多次。(调用次数取决于类层次关系)

分类方法

+load: 如 call_load_methods 中所写,分类方法会在所有类 load 方法调用后再统一被调用 +initialize: 使用 objc_msgSend,同名方法会覆盖,覆盖顺序取决于 .objc 文件的链接顺序,后链接的将覆盖前面的方法(目前的 Xcode 逻辑)。

显示调用 super

目前都不需要,相应流程中已考虑父类调用逻辑

⚠️ **GitHub.com Fallback** ⚠️