概述
前几天,针对一道面试题分析了一下OC对象的本质。如果有兴趣可以去看一下。全篇其实讲的就是实例对象。
objc的对象主要可以分为3种:
- instance对象(实例对象)
- class对象(类对象)
- meta-class对象(元类对象)
本文只分析这几种对象,涉及到的isa方面的会另开一篇博客专门分析。
instance
-
instance对象就是通过类alloc出来的对象,每次调用alloc都会产生新的instance对象。
-
instance对象在内存中存储的信息包括:
isa指针- 其他成员变量
class
-
我们可以通过很多方法来获取一个类对象:
- 实例对象调用
-class方法:
Class obj_class = [obj1 class];- 类调用
+class方法:
Class obj_class2 = [NSObject class];- 通过Runtime API:
Class obj_class3 = object_getClass(obj1); - 实例对象调用
这些方法获取的都是同一个对象,每个类在内存有且只有一个class对象。
- class对象在内存中储存信息主要包括:
isa指针superclass指针- 类型的属性信息(
@property),类的实例方法信息(instance method) - 类的协议信息(
protocal),类的成员变量(ivar)
meta-class
meta-class被称为元类对象。每个类的内存中有且只有一个meta-class对象。
meta-class对象中存储的信息主要包括:
- isa指针
- superclass指针
- 类的类方法信息(class method)
meta-class也是Class类型的,所以meta-class对象和Class对象的内存结构都是一样的。存储的信息不同就是说相关的成员变量为nil而已。
相关的API
-
获取:
object_getClass(id obj)函数同样也可以用来获取meta-class。//获取Class对象 Class cls = [NSObject class]; NSLog(@"%p",cls);//0x7fff93c6f118 //获取metaClass对象 Class metaClass = object_getClass([NSObject class]); NSLog(@"%p",metaClass);//0x7fff93c6f0f0 //这种方式只能获取Class对象,获取不到metaClass对象 Class class = [[NSObject class] class]; NSLog(@"%p",class);//0x7fff93c6f118 -
判断:
可以通过
Runtime API中class_isMetaClass()判断Class cls = [NSObject class]; NSLog(@"%d",class_isMetaClass(cls));//0 Class metaClass = object_getClass([NSObject class]); NSLog(@"%d",class_isMetaClass(metaClass)); //1
Object_getClass
在获取class对象和元类对象中,我们都使用了object_getClass(id obj)这个API。
总结一下:
NSObject *obj = [[NSObject alloc] init];
//传入instance对象返回class对象
Class cls = object_getClass(obj);
NSLog(@"%d",class_isMetaClass(cls));//0
//传入class对象返回meta-class对象
Class metaCls = object_getClass(cls);
NSLog(@"%d",class_isMetaClass(metaCls));//1