load方法说明
在Objective-C中,绝大多数类都继承自NSObject这个根类,而该类有load方法,可以用来实现初始化操作。其原型如下:
|
|
对于加入运行期系统中的每个类(class)及分类(category)来说,必定会调用此方法,而且仅调用一次。当包含类或分类的程序库载入系统时,就会执行此方法(通常指应用程序启动)。如程序是iOS平台设计的,则肯定会在此时执行。Mac OS X应用程序更自由一些,它们可以使用“动态加载”(dynamic loading)之类的特性,等应用程序启动好之后再去加载程序库。如果分类和其所属的类都定义了load方法,则先调用类里的,再调用分类里的。
执行load方法时,运行期系统处于“脆弱状态”。在执行子类的load方法之前,必定会先执行所有超类的load方法,而如果代码还依赖了其他程序库,那么程序库里相关类的load方法也必定会先执行。
load方法的妙用
简化AppDelegate类
随着项目功能的不断增加,我们有很多功能或者第三库需要启动项目时就加载,AppDelegate类就会越来越庞大。这样结构既不够清晰,而且耦合性比较强。
改进前:
|
|
改进后
目录结构如下:
初始化第三方库BYThirdPartService.m的代码如下:
|
|
初始化数据 BYInitData.m的代码(思路,具体代码根据自身项目的实际情况进行修改)
|
|
简化后AppDelegate如下:
|
|
当类被引入项目时, runtime 会向每一个类对象发送 load 消息. 神奇的load 方法, 会在每一个类甚至分类被引入时仅调用一次, 调用的顺序是父类优先于子类, 子类优先于分类. 而且 load 方法不会被类自动继承, 每一个类中的 load 方法都不需要像 viewDidLoad 方法一样调用父类的方法。
埋点统计
在iOS中,在运行时替换两个方法的实现,达到“勾住”某个方法并注入代码的目的。具体方法如下:
重载类的“+(void)load”方法,在程序加载到内存时利用Runtime的method_exchangeImplementations等接口将方法的实现互相交换。当方法M被调用时就会被勾住(Hook),执行我们的方法。
该技术称为Method Swizzling,属于面向切面编程(Aspect-Oriented Programming)的一种实现。
替换两个方法的实现,代码如下:
|
|
BYStatistics统计类下文会用到。利用神奇的load方法统计两个页面的展示与离开次数
|
|
load方法与initialize方法
NSObject的load方法和initialize方法都是用来实现初始化操作。
load方法
对于加入运行期系统中的每个类及分类来说,必定会调用此方法,而且近调用一次。当包含类或分类的程序库载入系统时,就会执行此方法,而这通常就是指应用程序启动的时候,若程序是为iOS平台设计的,则肯定会在此时执行。
如果分类和其所属的类都定义了load方法,则先调用类里的,在调用分类里的。在执行子类的load方法之前,必定会先执行所有超类的load方法,而如果代码还依赖了其他程序库,那么程序库里相关类的load方法也必定会先执行。
在整个应用程序执行load方法时都会阻塞initialize方法
它是“惰性”调用的,也就是说,只有当程序用到了相关的类时,才会调用。因此,如果某个类一直都没有使用,那么其initialize方法就一直不会运行。这也就等于说,应用程序无须先把每个类的initialize都执行一遍
注意事项
- 与其他方法不同,load方法不参与覆写机制
- load方法实现得精简一些,有助于保持应用程序的响应能力,也能
如有写的不对地方,请在评论区指出,谢谢!
请指明出处:
https://jingwanli6666.github.io/2016/11/08/%E7%A5%9E%E5%A5%87%E7%9A%84load%E6%96%B9%E6%B3%95/