这篇博客介绍的就是网上很流行的一张图关于isa和superclass的关系的解释!
![](https://img.haomeiwen.com/i3291334/d5b872a3bbc31061.jpeg)
温馨提示:如果你没有接触类的对象不了解的话,这篇博客有点费解,建议先看一下深入探究NSObject对象。
一、isa
首先看下面的代码
![](https://img.haomeiwen.com/i3291334/3c38eeb41f52091a.jpeg)
@interfance GDStudent : GDPerson
@interfance GDPerson : NSObject
我们知道GDStudent的class的内存中存储的有:isa、superclass、对象方法、属性、协议、成员变量 等等。
我们知道GDPerson的class的内存中存储的有:isa、superclass、对象方法、属性、协议、成员变量 等等。
我们知道NSObject的class的内存中存储的有:isa、superclass、对象方法、属性、协议、成员变量 等等。
好,现在我们写一个代码:
GDPerson*person = [[GDPersonalloc]init];
[person personInstanceMethod];
首先person是实例对象,我们知道是在实例对象的内存里面,而personInstanceMethod的对象方法是在person的class里面,所以我们猜测,实例对象和类对象肯定有某种关联,不然实例对象不可能找到类对象的对象方法。
常见面试题
对象的isa指针指向哪里?
对象的isa指针是指向类对象,类对象的isa指针是指向元类对象。从第一张图的虚线也是很容易看出来。
![](https://img.haomeiwen.com/i3291334/50826e2a7382268a.jpeg)
二、superclass
superclass翻译就是父类的意思,是不是已经思考它的用处了哈,
比如我现在定义一个main的分类,在分类里面写
+(void)test;方法,然后在.m文件实现这个方法。
GDStudet*stu = [[GDStudetalloc]init];
[stu test];
上面这段代码,它的实质是怎么运行的,我们分析一下,test肯定是NSObject的类方法,而GDStudet是继承于GDPerson,GDPerson是继承NSObject,而类方法是存在NSObject元类对象内存里面,所以很容易得出下面的结论:
stu首先是通过isa指针找到stu的class对象内存,然后通过stu的class对象的isa指针找到stu的meta-class元类对象,在stu的meta-class元类对象内存中找test类方法,找不到以后通过stu的meta-class元类对象的superclass找到person的meta-class元类对象,然后在person的meta-class元类对象内存中找test,然后还是找不到,最后就是通过person的meta-class元类对象的superclass找到NSObject的meta-class元类对象,然后再去找test方法,最后就找到了实现。
假如test在.m文件没有实现的话,其实也能运行成功,就会报经典得错误:
terminating with uncaught exception of type NSException
拓展
![](https://img.haomeiwen.com/i3291334/9ccd47d549f3c145.jpg)
红线圈里面是怎么回事呢?
首先我们可以这样操作在分类里面写
+(void)test;方法,然后在.m文件这样实现-(void)test{ }。
[GDStudet test];
然后运行,结果发现是正常运行的,并且也调用了-(void)test{ }方法,这里就可以看出meta class是会找到class内存中找test方法,实际上,runtime发消息机制类似这样
[GDStudet test];类似 objc_msgSend([GDStudet class], @selector(test)),
这里可以看出它是没有区分+和-号方法,所以能调用到-(void)test{ }。实现,
到这里我们很容易看出对象方法和类方法的调用实质!代码就少,就不上传了!
如果觉得我写得对你有所帮助,请关注我,我会持续更新😄
网友评论