一个NSObject对象占用多少内存?
系统分配了16个字节给NSObject对象(通过malloc_size函数获得)
但NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInstanceSize函数获得)
对象的isa指针指向哪里?
【iOS面试题--基础】instance对象的isa指向class对象
class对象的isa指向meta-class对象
meta-class对象的isa指向基类的meta-class对象
OC的类信息存放在哪里?
对象方法、属性、成员变量、协议信息,存放在class对象中
类方法,存放在meta-class对象中
成员变量的具体值,存放在instance对象
Category的实现原理
Category编译之后的底层结构是struct category_t,里面存储着分类的对象方法、类方法、属性、协议信息
在程序运行的时候,runtime会将Category的数据,合并到类信息中(类对象、元类对象中)
Category和Class Extension的区别是什么?
Class Extension在编译的时候,它的数据就已经包含在类信息中
Category是在运行时,才会将数据合并到类信息中
Extension 可以添加属性、成员变量,而Category 一般不可以 需要运用runtime 库objc_setAssociatedObject / objc_getAssociatedObject 函数来解决。
load、initialize方法的区别什么?它们在category中的调用的顺序?以及出现继承时他们之间的调用过程?
+load方法会在runtime加载类、分类时调用,每个类、分类的+load,在程序运行过程中只调用一次
调用顺序:
先调用类的+load,按照编译先后顺序调用(先编译,先调用)
调用子类的+load之前会先调用父类的+load
再调用分类的+load,按照编译先后顺序调用(先编译,先调用)
+initialize方法会在类第一次接收到消息时调用
调用顺序:
先调用父类的+initialize,再调用子类的+initialize
(先初始化父类,再初始化子类,每个类只会初始化1次)
+initialize和+load的很大区别是,+initialize是通过objc_msgSend进行调用的,所以有以下特点
如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
如果分类实现了+initialize,就覆盖类本身的+initialize调用