导语:让我们简单的理一理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函数里面完成。