
2.在调用 load 之前调用父类 load 方法.
3.分类 load 方法不会覆盖本类的 load 方法.
4.initialize 方法先初始化父类,之后再初始化子类.
5.如果子类未实现 initialize 方法,就会调用父类的 initialize 方法.
6.如果分类实现了 initialize 方法,会覆盖本类 initialize 方法.
load 函数是当类或分类(Category)被加载到 Objective-C runtime 时(就是被引用的时候)被调用的,实现这个方法可以让我们在类加载的时候执行一些类相关的行为。当类被引用进项目的时候就会执行 load 函数(在 main 函数开始执行之前),与这个类是否被用到无关,每个类的 load 函数只会自动调用一次。load 函数调用特点如下:
1、当父类和子类都实现 load 函数时,二者的 load 方法都会被调用,父类的 load 方法执行顺序要优先于子类。
2、当子类未实现 load 方法时,在加载该子类时,不会去调用其父类 load 方法。
3、类中的 load 方法执行顺序要优先于类别(Category)。
4、当有多个类别(Category)都实现了 load 方法,这几个 load 方法都会执行,但执行顺序与编译顺序一致,即与类别在 Compile Sources 中出现的顺序一致。
5、当有多个不同的类的时候,每个类 load 执行顺序与编译顺序一致,即与其在 Compile Sources 出现的顺序一致。
initialize 函数是在类或者其子类的收到第一条消息之前调用。这里所指的消息包括实例方法和类方法的调用。也就是说 initialize 方法是以懒加载的方式被调用的,如果程序一直没有给某个类或它的子类发送消息,那么这个类的 initialize 方法是永远不会被调用的。
1、父类的 initialize 方法会比子类先执行。
2、当子类未实现 initialize 方法时,在该子类收到第一条消息之前,会调用父类 initialize 方法,子类实现 initialize 方法时,则会覆盖父类 initialize 方法。有点多态的意思。
3、当有多个 Category 都实现了 initialize 方法,会覆盖类中的方法,只执行最后那个被编译的,即 Compile Sources 列表中最后一个 Category 的 initialize 方法。
对于 load 和 initialize 方法,我们不要显示的调用 super 的对应方法。
1、子类里通过super关键字直接调用父类公有方法。
输出结果如下:
2、子类覆盖父类方法
输出结果如下:
第一个是子类未实现同名方法overMethod,第二个是现实了同名方法overMethod
1、利用构建的方式来调用先获取父类方法,if (super_func) 是判断父类是否包含的此方法,如果含有此方法则调用,否则不调用。
2、可以利用runtime的消息发送机制。这个方法是利用遍历父类中的所有方法来判断是否包含某一方法,弊端是当这个父类方法很多时,而又需要频繁调用此方法时就会引起不必要的消耗。如果父类包含此方法就直接利用objc_msgSendSuper发送消息就可以了。
需要声明#import <objc/message.h>。
这里调用objc_msgSendSuper方法需要将ENABLE_STRICT_OBJC_MSGSEND设置为NO。
1、分类在不修改原有类的基础上,为一个类扩展方法,最主要的是可以给系统类扩展我们自己定义的方法,如果要重写现有类的方法,请考虑使用继承。
2、Category编译之后的底层结构是struct category_t,里面存储着分类的对象方法、类方法、属性、协议信息
在程序运行的时候,runtime会将Category的数据,合并到类信息中(类对象、元类对象中),如果分类有同名方法会先调用分类同名方法。
3、利用runtime遍历主类的方法列表(包含类分类的方法),获取原类方法在方法列表中的索引,用IMP直接调用该方法。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)