OC对象 - +load、initialize方法

本文详细解析了Objective-C中+load和initialize方法的调用时机、顺序,强调了+load仅在类加载时调用一次且遵循特定顺序,而initialize在类首次接收到消息时调用,子类的initialize可能因父类或分类的存在而被多次调用。
摘要由CSDN通过智能技术生成

OC对象 - +load、initialize方法

1. +load方法

1.1 调用时机

  • +load方法会在runtime加载类、分类时调用
  • 每个类、分类的+load,在程序运行时只调用一次

1.2 调用顺序

  1. 先调用父类的+load
  • 按照编译先后顺序调用(先编译,先调用)
  • 调用子类的+load之前会先调用父类的+load
  1. 再调用分类的+load
  • 按照编译先后顺序调用(先编译,先调用)

1.3 码上验证

从类文件列表看到,ZSXPerson在其两个分类的后面编译的,但是它的+load始终是最先调用的

1.4 调用方式

从源码可以看出

+load方法是根据方法地址直接调用,并不是经过objc_msgSend函数调用

2. initialize方法

2.1 调用时机

  • +initialize方法会在类第一次接收到消息时调用

2.2 调用顺序

  1. 先调用父类的+initialize,再调用子类的+initialize
  2. 先初始化父类,再初始化子类,每个类只会初始化1次

注:如果有分类的情况,分类+initialize方法会覆盖掉+initialize方法

2.3 码上验证

2.3.1 验证父类和子类的情况

ZSXStudenZSXPerson的子类,给ZSXStuden发送消息,先执行父类ZSXPerson+initialize方法,再执行子类ZSXStuden+initialize方法

2.3.4 验证含有分类的情况

ZSXStudenZSXPerson的子类,ZSXPerson有分类ZSXPerson+_11,分类中也实现了+initialize方法。给ZSXStuden发送消息,因为分类方法覆盖了类的方法,会先执行父类分类ZSXPerson+_11+initialize方法,再执行子类ZSXStuden+initialize方法

2.4 调用方式

我们注意到,+initialize实在第一次收到消息时调用,可以推断出他是跟runtime有关的,所以:

  • +initialize是通过objc_msgSend进行调用的

3. +load、initialize方法的区别

+initialize和+load的很大区别是,+initialize是通过objc_msgSend进行调用的,所以有以下特点

  • 如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
  • 如果分类实现了+initialize,就覆盖类本身的+initialize调用

3.1 验证+initialize可能被调用多次

因为+initialize走了runtime机制调用,我们知道,子类收到消息时,如果自身找不到方法实现,会到父类中继续查找

  • 我们多创建一个ZSXPerson的子类ZSXTeacher
  • ZSXPerson有2个子类:ZSXStudenZSXTeacher
  • ZSXTeacher中没有+initialize方法
  • 我们分别给ZSXStudenZSXTeacher发送消息,查看+initialize方法调用情况、

@oubijiexi

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值