1.一个 NSObject 对象占用多少内存空间?
一个 NSObject对象都会分配 16byte 的内存空间。实际上在 64位 下,只使用了 8byte;
在32位下,只使用了 4byte。
2.OC对象的分类?
OC对象主要可以分为3种
(1)instance对象(实例对象):instance实例对象就是通过alloc出来的对象,每次调用alloc都会产生新的instance对象
(2)class对象(类对象):每个类的内存中有且只有一个类对象
(3)meta-class对象(元类对象):每个类的内存中有且只有一个元类对象
实例对象的存储信息
(1)isa指针
(2)其他成员变量
类对象的存储信息
(1)isa指针
(2)superClass指针
(3)类的属性信息(@property),类的对象方法信息(method),类的协议信息(protocol),类的成员变量信息(ivar)
元类的存储信息
(1)isa指针
(2)superClass指针
(3)类的属性信息(@property),类的对象方法信息(method),类的协议信息(protocol),类的成员变量信息(ivar)
实际上instance实例的对象的isa指针指向class,找到class类以后,再在class类中找存储于其中的对象方法方法进行调用。
调用类方法的过程也是如此,class类通过其内部的isa指针找到meta-class类中存储的类方法,然后再进行调用。
isa
instance的isa指向class
class的isa指向meta-class
meta-class的isa指向基类的meta-class
superclass
class的superclass指向父类的class
如果没有父类,superclass指针为nil
meta-class的superclass指向父类的meta-class
基类的meta-class的superclass指向基类的class
instance 调用对象方法的轨迹
isa找到class,方法不存在,就通过superclass找父类。
class 调用类方法的轨迹
isa找meta-class方法不存在,就通过superclass找父类。
3.KVO实现原理?
KVO(key value observing)键值监听是我们在开发中常使用的用于监听特定对象属性值变化的方法,常用于监听数据模型的变化
KVO是为了监听一个对象的某个属性值是否发生变化。在属性值发生变化的时候,肯定会调用其setter方法。所以KVO的本质就是监听对象有没有调用被监听属性对应的setter方法
1、利用RuntimeAPI动态生成一个子类NSKVONotifying_XXX,并且让instance对象的isa指向这个全新的子类NSKVONotifying_XXX
2、当修改对象的属性时,会在子类NSKVONotifying_XXX调用Foundation的_NSSetXXXValueAndNotify函数
3、在_NSSetXXXValueAndNotify函数中依次调用 - 1、willChangeValueForKey - 2、父类原来的setter - 3、didChangeValueForKey,didChangeValueForKey:内部会触发监听器(Oberser)的监听方法( observeValueForKeyPath:ofObject:change:context:)
4.KVC实现原理?
KVO的setValue:forKey原理
1、按照setKey,_setKey的顺序查找成员方法,如果找到方法,传递参数,调用方法
2、如果没有找到,查看accessInstanceVariablesDirectly的返回值(accessInstanceVariablesDirectly的返回值默认是YES),
返回值为YES,按照_Key,_isKey,Key,isKey的顺序查找成员变量,如果找到,直接赋值,如果没有找到,调用setValue:forUndefinedKey:,抛出异常
返回NO,直接调用setValue:forUndefinedKey:,抛出异常
KVO的ValueforKey原理
1、按照getKey,key,isKey,_key的顺序查找成员方法,如果找到直接调用取值
2、如果没有找到,查看accessInstanceVariablesDirectly的返回值
返回值为YES,按照_Key,_isKey,Key,isKey的顺序查找成员变量,如果找到,直接取值,如果没有找到,调用setValue:forUndefinedKey:,抛出异常
返回NO,直接调用setValue:forUndefinedKey:,抛出异常