14:+load方法调用原理
load方法是在runtime加载类,分类的时候调用,每个类,分类的load方法,在程序运行过程中只会加载一次,和其他方法调用不同,不是通过消息机制(isa一层层查找),而是在类,分类加载是直接通过函数地址调用,通过指针指向类,分类load方法地址,然后直接调用。
总结:(可以看出确实是优先调用类的load方法,然后调用分类的load方法,分类的load方法不会覆盖类的load方法)
a:一定是优先调用类的load方法,然后调用分类的load方法,这个和编译顺序无关
b:类与类之间的load方法调用顺序和编译顺序有关
c:调用子类的load方法之前,会保证其父类的load方法已调用,即父类的load方法优先调用,即使父类编译顺序在子类后面(不会被覆盖)
d:分类的load方法调用顺序与编译顺序有关,先编译先调用
14.1: +load方法会在runtime加载类、分类时调用
每个类、分类的+load,在程序运行过程中只调用一次
调用顺序
先调用类的+load
按照编译先后顺序调用(先编译,先调用)
调用子类的+load之前会先调用父类的+load
再调用分类的+load
按照编译先后顺序调用(先编译,先调用)
15;+initialize方法调用原理
initialize方法会在类第一次接收到消息时调用,并且它的调用顺序优先调用父类的initialize,再调用子类的initialize,前提是父类的initialize没有调用过。
16:+load、+initialize方法的区别什么?它们在category中的调用的顺序?以及出现继承时他们之间的调用过程?
区别:
调用方式:load是根据函数地址直接调用,initialize是通过objc_msgSend调用
调用时刻:load是runtime 加载类,分类的时候调用(只会调用一次),initialize是类第一次接收到消息的时候调用,每一个类只会initialize一次(父类的initialize方法可能会被被多次调用);
load方法:先编译哪个类,就先调用哪个类的load,在调用load之前会先调用父类的load方法;分类中load方法不会覆盖本类的load方法,先编译的分类优先调用load方法;
initialize方法:先初始化父类,之后再初始化子类,如果子类没有实现+initialize,会先调用父类的+initialize(所以父类的+initialize可能会被多次调用),如果分类实现了+initialize,就会覆盖类本身的+initialize调用;
17:Category能否添加成员变量?如果可以,如何给Category添加成员变量?
不能直接给category添加成员变量,但是可以间接实现category有成员变量的效果。
我们可以使用runtime的API,关联对象
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key, id _Nullable value, objc_AssociationPolicy policy)
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key)
网友评论