在利用OC开发应用程序中,需要大量创建对象,那么它的过程是什么呢?
比如:NSArray *array = [[NSArrayalloc] init];
在说明之前,先把OC的Class描述一下:
Class
Objective-C类是由Class类型来表示的,它实际上是一个指向objc_class结构体的指针。它的定义如下:
typedef struct objc_class *Class;
查看objc/runtime.h中objc_class结构体的定义如下:
struct objc_class {
Class isa;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE; // 父类
const char *name OBJC2_UNAVAILABLE; // 类名
long version OBJC2_UNAVAILABLE; // 类的版本信息,默认为0
long info OBJC2_UNAVAILABLE; // 类信息,供运行期使用的一些位标识
long instance_size OBJC2_UNAVAILABLE; // 该类的实例变量大小
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 该类的成员变量链表
struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法定义的链表
struct objc_cache *cache OBJC2_UNAVAILABLE; // 方法缓存
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 协议链表
#endif
} OBJC2_UNAVAILABLE;
说明:
- isa:需要注意的是在Objective-C中,所有的类自身也是一个对象,这个对象的Class里面也有一个isa指针,它指向metaClass(元类),我们会在后面介绍它。
- super_class:指向该类的父类,如果该类已经是最顶层的根类(如NSObject或NSProxy),则super_class为NULL。
- cache:用于缓存最近使用的方法。一个接收者对象接收到一个消息时,它会根据isa指针去查找能够响应这个消息的对象。在实际使用中,这个对象只有一部分方法是常用的,很多方法其实很少用或者根本用不上。这种情况下,如果每次消息来时,我们都是methodLists中遍历一遍,性能势必很差。这时,cache就派上用场了。在我们每次调用过一个方法后,这个方法就会被缓存到cache列表中,下次调用的时候runtime就会优先去cache中查找,如果cache没有,才去methodLists中查找方法。这样,对于那些经常用到的方法的调用,但提高了调用的效率。
- version:我们可以使用这个字段来提供类的版本信息。这对于对象的序列化非常有用,它可是让我们识别出不同类定义版本中实例变量布局的改变。
下面以array对象为例来说明其执行过程:
- [NSArray alloc]先被执行。因为NSArray没有+alloc方法,于是去父类NSObject去查找。
- 检测NSObject是否响应+alloc方法,发现响应,于是检测NSArray类,并根据其所需的内存空间大小开始分配内存空间,然后把isa指针指向NSArray类。同时,+alloc也被加进cache方法列表里面。
- 接着,执行-init方法,如果NSArray响应该方法,则直接将其加入cache方法列表;如果不响应,则去父类查找。
- 在后期的操作中,如果再以[[NSArray alloc] init]这种方式来创建数组,则会直接从cache方法列表中取出相应的方法,直接调用。