在上篇文章中,我们了解到OC对象分为实例对象、类对象和元类对象三种。
实例对象主要存放有isa指针和成员变量的值;
类对象主要存放isa指针、superClass指针、成员变量(类型、成员变量名)、属性、遵循的协议和实例方法(-方法);
元类对象主要存放isa指针、superClass指针和类方法(+方法)。
那么每个实例对象都有一个类对象和元类对象,这三者是怎样联系起来的呢,今天我们一起来探讨一下。
首先我们来看一张很经典的图:
这幅图表达的意思是:
1.实例对象的isa指针指向类对象;
2.类对象的isa指针指向元类对象;
3.元类对象的isa指针指向元类的基类对象,因为在OC中常用的类的基类都是NSObject,也就是说元类的isa指针都指向NSObject的元类,包括NSObject元类本身也指向自己。
4.类对象的superClass指针指向父类的类对象;一直指向NSObject,由于NSObject没有父类,所以NSObject的superClass指针为空;
6.元类的superClass指针指向父类的元类对象,一直指向NSObject的元类。
7.注意右上角的那条曲线,NSObject元类的superClass指向NSObject的类对象。
是不是被绕晕了。。。。
还是看代码来的实在:
老规矩,我们创建两个类,Student和Person类,Student继承自Peson类。Person类声明test实例方法,在Student和Person中分别实现。
同时创建NSObject的一个分类,也实现test实例方法:
下面我们通过实例对象来进行验证刚才的结论:
代码第45行:person对象通过isa指针指向Person的类对象,在Person类对象中找到test方法,然后调用Person 的 test方法。
代码第46行:student实例,通过isa指针指向Student的类对象,在类对象中找到了test方法实现,调用Student 的 test方法。
代码第48行:调用Student的类方法test,首先通过Student类对象的isa指针指向Student的元类,在Student的元类中找test的类方法,没有找到;
继而通过Student元类的superClass指针指向父类Person的元类,在Person的元类的类方法列表中查找test的实现,也没有找到;
继续通过Person元类的superClass指针指向NSObject的元类,在NSObject的类方法列表中也没有找到test的实现;
继续通过NSObject元类的superClass指针,由于NSObject元类的superClass指针指向NSObject的类对象,就在NSObject类对象的方法列表中找test的实现。由于我们在NSObject的Category中实现了-(void)test 方法,继而调用之。
以上解读阐述了isa和superClass的指向关系,同时也简单映射出Object-C的方法调用途径,关于方法调用与转发,我们会在后续中进行详细讲解。
网友评论