OC中类的Self 和 Super调用方法的本质

问题引出:神经病院objc runtime入院考试

享受一下来自底层的高端操作。


先上图为敬
Vc类:
OC中类的Self 和 Super调用方法的本质

Son类
OC中类的Self 和 Super调用方法的本质

打印结果:
OC中类的Self 和 Super调用方法的本质

首先创建一个 测试,我的思路是:创建一个son,一个father,son的父类的father,然后在son类中 提供对象方法,同时在h文件暴露该方法,在Vc中进行调用测试,发现结果在调用[super class]的时候确实是打印的SonViewCOntroller。

原因(底层方法,现在Apple不让查看了):1、在调用[self class]的方法的时候,其实是调用的
id objc_msgSend(id theReceiver, SEL theSelector, ...)
第一个参数是,消息接受者,按照咱们的例子,应该是sonVc,
sel则为方法,该方法如果在sonVc类中没有找到,就会不停地往上一级查找,知道找到NSObject中的sel。
2、在调用[super class]的方法的时候,其实是调用的
id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
其中super是一个结构体

struct objc_super {
id receiver;
Class superClass;
};

在方法中的第二个参数所要找的sel,会从这个结构体的Class 来定位,找呀找,还是在NSObject中找到sel,于是调用 objc_msgSend(objc_super->receiver, @selector(class)) 。

总结1、2:1、假如self和super调用的方法是在父类的父类中,打印[** class],其实就是打印的theReceiver,因为无论是[self class],还是[super class]他们的 theReceiver都是一样的。不要问为什么会这样,你可以想想在写单例的时候,为什么还会用到self==[super init]的这样的判断,其实本来可以不写,但是防止内存泄漏的问题,把这个写上,可以预防程序崩溃。

2、引出新的问题:在一个类中可以调用 [super init],既然能找到super的这个类,肯定是有isa指针指向super所在的 栈区,堆区就会有相应的空间。所以类是对象吗?应该怎么理解呢?