前面几篇文章主要讲解了NSObject实例对象在内存中如何分布,但是我们都知道一个类中,肯定不止存在成员变量,还有属性,对象方法,类方法和遵循的一些协议,那么这些内容在内存中是如何布局的呢?这个就是我们今天需要探讨的内容。
首先我们需要明白的是,在Object-C中,对象是分为三类,即实例对象、类对象和元类对象。一个实例对象对应唯一的类对象,一个类对象对应唯一的元类。反过来,一个元类对应一个类对象,一个类对象可以实例化很多实例对象,说的有点绕,我们通过代码来看一下。
首先我们分别创建实例对象、类对象和元类对象,代码如下:

实例对象我们可以通过 alloc 方法来创建。
类对象我们可以通过四种方法来创建,分别是 调用类的class方法,调用对象的class方法,调用objc_class()和object_class()方法。
注意objc_class()和objcet_class()方法的区别:
objc_class()方法是接受一个字符串作为参数classNameString,然后返回以classNameString作为类名的类对象,如果不存在以classNameString为类名的类时,返回nil。
object_class()方法接受一个对象obj,当obj是一个实例对象时,返回结果为类对象;当obj是一个类对象时,返回结果是一个元类对象。
元类对象通过 object_class()方法传入类对象获得。
下面我们看一下输出结果:

注意看结果:通过alloc()创建的三个实例对象,拥有不同的地址,说明每个对象是相互独立的,这个并不陌生。
由于我们获取的都是NSObject的类对象,不管是通过哪种方法,最终得到的都是NSObject类型,地址是0x7fffa6ec2140,也就是说在系统运营过程中,只有一个NSObject类对象。
同时元类对象也只有一份,类型是NSObject。
从上面的分析中,我们得出结论,一个实例对象的类对象和元类对象在内存中只保存一份,可以有多个实例对象进行公用。那么类对象和元类对象中,究竟存放的是什么内容,可以令所有的实例对象进行公用呢?
我们已经明白,在实例对象中,只存放了成员变量,具体来说是成员变量的值,同时还有一个比较特殊的值isa指针,在每个实例对象中都有保存。
由于成员变量信息、属性、遵循的协议、实例方法在每个类中,只需要保存一份就可以供所有实例对象进行公用,所有这些信息存放在类对象就可以。除此以外,类对象中还保存了isa指针和superClass指针。
剩下的只剩类方法了,也就是我们经常定义的以 + 开头的方法,就是存储在元类(metaClass)中了。当然,在元类对象中也保存了一份isa指针和superClass指针。
那么一个类的实例对象、类对象和元类对象究竟是不是像我们说的这样来分工,又是如何进行关联的呢,且听下回分解\(^o^)/~
网友评论