准备工作
首先我们创建一个继承于NSObject的CFPerson类,在mian 函数初始化,再加一个断点
#import "CFPerson.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
CFPerson *person = [CFPerson alloc];
NSLog(@"Hello, World! %@",person);
}
return 0;
}
接下来看看打印信息
当前类信息
p/x 0x0000000100002150 拿到元类
**元类&**0x0000000ffffffff8ULL打印出得到一个地址
在打印元类的指向,可得到内存信息
po 0x00000001003340f0得到NSObject类
以上打印可分析拟草一个类对象执行过程指向图:
我们再来验证一下:
打印结果发现0x0000000100334140地址不一样,并不是NSObject类,那么它可能会是什么呢?可能是第二个NSObject类。
我们知道类的信息在内存里永远只存在一份。
分析类对象内存存在个数
贴上代码
void cfTestClassNum(){
Class class1 = [CFPerson class];
Class class2 = [CFPerson alloc].class;
Class class3 = object_getClass([CFPerson alloc]);
Class class4 = [CFPerson alloc].class;
NSLog(@"\n%p-\n%p-\n%p-\n%p",class1,class2,class3,class4);
}
看下打印结果:
可以看出类对象地址都一样,因此类的信息在内存里永远只存在一份
怎样拿到元类?
首先打印当前地址拿到当前iso,通过当前的iso&ISA_MASK 0x0000000ffffffff8ULL,变可得到一个地址0x00000001003340f0,于之前po打印的NSObject地址0x00000001003340f0相等,因此它并不是NSObject类,而是NSObject元类(根元类)
此刻已经到了根元类,再往下走
继续打印当前地址iso信息便会得到根元类的iso,拿到根元类iso再&ISA_MASK 0x0000000ffffffff8ULL得到地址0x00000001003340f0,再再打印其内存情况。
此刻我们发现其内存地址信息与之前的一样,这便意味着NSObject根元类还是指向NSObject根元类,即指自己,那么之前拟草的类对象执行过程指向图得更新一下了:
对于NSObject没有元类的指向,其余定义的类都满足实例对象Instance of Superclass[class]——>当前类Subclass[class]——>当前元类Superclass[class]