NSOiOOC对象模型及运行时(1/3)-对象模型 2014-01-10
Objective-C 类和对象的声明
Objective-C的Runtime是开源的,在Obj4-532.2之后,NSObject也开源了,可以在这里下载
下面的代码就是节选自最新的代码551.1.
1 | //objc.h |
1 | //runtime.h |
在objc.h里,声明了两个类型:Class
和id
,分别代表Objective-C
(以下简称OC
)类和实例对象,可以看作是泛型
。在runtime.h
中,我们看到OC类和对象其实就是两个结构体,其中第一个变量就是一个指向自己所属类的isa
指针。
所以根据上面的声明,在OC中,一个对象的类由它的 isa 指针决定,isa 指针指向这个对象所属的Class。或者可以这么说:凡是首地址是isa指针的结构体,都可看作OC类。
当然后一句是不严谨的,根据下面的代码,我们发现,一个OC对象,还要包含ISA(),initIsa(),getIsa(),changeIsa()
等5个方法。理所当然的,在NSObject.h中,NSObject也包含了一个isa指针。
Objective-C 类和对象的定义
1 | //objc-private.h |
1 | //objc-runtime-new.h |
OC的对象定义在objc-private.h中,除了isa指针外,还包含了另外5个方法,简单说下其中两个:
getIsa()是获取isa指针的方法,如果isa不是TaggedPointer,则将isa转为Class类型返回;如果isa是TaggedPointer,则返回经过计算的指针。关于TaggedPinter的内容,可以参考唐巧的博文
changeIsa() 。。可能和isa swizzle 有关,以后再说
OC对象模型分析
OC的类的定义在objc-runtime-new.h中,比较特殊,它是继承自OC对象,所以所有的OC类都可以看作是对象—元类
的对象;OC类还增加了包括superClass
指针和和方法列表缓存cache_t cache
等,superClass指向父类,方法cache是为了提高访问效率而设定的,用来缓存调用过的方法,这样下次再调用的时候就能提高查找效率。所以在运行时,通过isa指针就能找到真正调用的方法,其isa指针和superClass指针的指向关系如下图所示:
根据上图,我们可以看到:
创建一个OC类其实是创建一个类对(ClassPair)-类和元类,类的isa指针指向元类,元类的isa指向根元类,即图中的NSObject元类,根元类的isa指向它自己,形成闭环,保证isa指针永远不会为空 —同时这也会使得一个类(Class)可以
响应NSObject
的所有实例方法isa指针指向就是消息传递的方向,如果通过isa指针没找到此消息,则继续通过superClass指针查找,如下图所示。
类中含有实例方法列表,元类中含有类方法列表;NSObject元类的superClass指向NSObject实例,所以,理论上给元类发消息,能找到NSObject的实例方法。
为什么要有元类呢?一是可以分离类方法和实例方法;二是元类总是会保证 Class 对象会有从基类继承的所有的的实例和类方法。
运行时的消息传递
在运行时动态创建一个类
动态创建一个类,需要三个步骤:
- 1、为“class pair”-类和元类 创建存储空间(使用 objc_allocateClassPair).
- 2、为这个类添加所需的 methods 和 ivars(使用 class_addMethod).
- 3、注册这个类,然后就可以使用了(使用 objc_registerClassPair).
下面的代码在运行时创建了一个 NSError 的子类同时为它添加了一个方法:
1 | Class newClass = |
添加的方法使用叫 ReportFunction 的函数作为实现,定义如下:
1 | void ReportFunction(id self, SEL _cmd) |
isa swizzling
KVO
(key-value observer)就是通过isa swizzling
来实现的。
当我们为一个类的某个属性添加observer时候,框架自动创建这个类的一个子类,并且修改这个类的isa指向这个新的子类。
由于在ios中函数调用都是转化为isa查表形式,所以这次查得时新的子类的表,
也就是说对类的函数调用被子类给拦截了,在拦截的实现中就可以通知observer了。
修改类的isa被称为isa-swizzling技术。isa-swizzling就是类型混合指针机制。KVO主要通过isa-swizzling,来实现其内部查找定位的。
参考资料:
3.what is meta class in objective-c
4.Objective-C 中的 Meta-class 是什么?
5.Object, Class and Meta Class in Objective-C