load and initialize

本文探讨了Objective-C中基类NSObject的重要方法load与initialize的作用及调用时机。load方法在类加载到进程地址空间时由运行时系统调用,而initialize则在类首次接收消息前被调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NSObject是一切OC类的基类,所以我们必须对NSObject所有的方法有一个清楚的认识。

+ (void)load;

当类或者分类被加入到runtime时,load方法会被调用,也就是说在main循环开始前load方法就已经被调用。

(当类被加载到进程的address space时,runtime就会给每个类发送load消息。For classes that are in a shared (dynamically-loaded) library, the runtime sends the load message just after the shared library is loaded into the process's address space.)

由于我们不能确定类加载到runtime中的时间,所以我们要避免在load方法中调用其他oc类。

注意:

  • 类的load方法,是在父类的load方法之后调用的
  • 分类的load方法,是在类的load方法之后调用的
  • 测试发现,只要类被加载到complie source中,即使没使用它,该类一样会被加载到runtime中
  • 在load中创建的对象在main循环之前,它们并没被假如到AutoreleasePool中,需要自己手动来处理

+ (void)initialize;

当类,或者任何继承资它的类,在发送第一个消息之前,runtime会发送initialize消息给该类

  • 父类先收到initialize消息,子类再收到
  • 如果子类没有实现initialize方法,父类可能收到initialize消息(),可以使用下面的方法来阻止收到多次消息
1 + (void)initialize {
2   if (self == [ClassName self]) {
3     // ... do the initialization ...
4   }
5 }
View Code
  • 每个类的initialize只会调用一次
  • initialize是线程安全的,所以尽量在initialize方法中做较少的事

源代码分析:

运行时在调用_class_lookupMethodAndLoadCache时,会先调用void _class_initialize(Class cls),查找oc的源代码(http://opensource.apple.com/source/objc4/objc4-646/runtime/objc-initialize.mm),实际上会先递归调用父类的_class_initialize方法,调用成功后,在调用((void(*)(Class, SEL))objc_msgSend)(cls, SEL_initialize),即调用自己的initialize方法。

总结来说:如果A:B:C:NSObject,当对A第一次调用方法时,会先调用B的initialize方法,在调用A的initialize方法。

转载于:https://www.cnblogs.com/wustlj/p/3625274.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值