浅谈系列-load 和 initialize的调用时机和实际运用

导语:让我们简单的理一理load方法和initialize这两个方法,以及在应该如何合理利用这两个方法。

浅谈系列-分类的结构和加载时机

+ load 方法

  • load方法是runtime在加载类,分类的时候调用的,在程序运行当中只会调用一次。

我们都知道OC的方法调用其实是通过runtime的消息机制完成的,但是load方法的调用确不是这样。如果按照一般方法调用程序,通过我们浅谈系列关于分类加载到主类的流程来看,分类的方法调用优先级高于主类。

那么category的load方法理应先于主类调用,或者说调用了分类的load的方法主类的就不会调用

事实却不是这样,其实load不是通过objc_msgsend消息机制调用的,而是通过地址指针直接调用的,所以不受分类方法优先调用的限制。

load 载入时机
1. 系统会通过指针先调用主类的load方法,再调用分类的load方法
2.不同的分类,按照先编译先调用的顺序调用load方法
3.如果这个类有父类,先调用父类的load方法,再调用自己的
4.在程序层面,不同的类也是按照先编译先调用的顺序调用load方法
  • 我们平时喜欢把一些一次性操作放在load方法里,这样做是否合适呢?

这个要分开看:

1.如果这写操作并不是很耗性能,可以放在此处。

2.如果是一些高性能操作,请不要在此处理。

原因:runtime加载数据在APP的启动阶段,在load_images中调用call_load_methods,通过此方法列表调用所有类和分类的load方法。如果load方法里都是一些高耗性能操作,就会影响到APP的启动。

+ initialize 方法

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

  • 与load方法不一样的是,initialize是通过runtime的objc_msgsend调用的。

initialize方法调用顺序
1. 如果分类实现了initialize方法,会调用分类的initialize方法(类似于覆盖了主类的initialize方法)
2. 如果子类没有实现initialize方法,会调用父类的initialize方法(因此父类的initialize可能会被多次调用,但是只有第一次调用是真正初始化父类,后面的调用都是通过调用父类的initialize初始化子类)
3. 系统会先调用父类的initialize,再调用子类的initialize,即先初始化父类,再初始化子类,且每个类只会初始化一次

注意:父类的initialize可能会被多次调用,但并不是多次初始化。

由于initialize有可能被多次调用,所以很多开发者不会在此做一次性操作,而去load方法里面写。

通过对比两个方法,我们可以知道,load是在APP启动期就被调用,而initialize是在类第一次接收到消息时被调用。

如果站在程序启动优化这个角度来看,推荐适度把一些耗时或者耗性能工作方法到initialize来做,可以把一次性操作放到GCD的once函数里面完成。

浅谈系列-OC对象创建出来到底是怎么样的呢

浅谈系列-OC方法调用到底是个什么流程

浅谈系列 – KVO&KVC到底是怎么样实现的

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享