OC 中的对象主要分3种
- instance对象,实例对象
- class 对象 ,类对象
- meta-class 对象 ,元类对象
instance对象
- 通过类alloc 出来的对象,每次调用alloc都会产生新的instance对象
- instance对象 在内存中存储着 成员变量和isa指针 没有方法
image.png
Class对象
获取Class对象的方法
NSObject * object1 = [[NSObject alloc]init];
NSObject * object2 = [[NSObject alloc]init];
Class objectClass1 = [object1 class];
Class objectClass2 = [NSObject class];
Class objectClass3 = object_getClass(object1);
- objectClass1 objectClass2 objectClass3 在内存中的地址是一样的
- object1 object2 在内存中的地址是不一样的
- 每个类在内存中有且只有一个class对象
- 类对象 内存中存储
isa指针
superclass指针
类的属性信息 (@property) 类的对象方法信息 (instance method)
类的协议信息 (protocol), 类的成员变量(描述)信息(ivar)
类对象.png
meta-class对象
获取方式
//注意这里需要传入 类对象
Class objectMetaClass = object_getClass([NSObject class]);
//原理是:判断isa 是不是指向自己 因为只有mate-class 是这样的
object_getClass
image.pngobjc_getClass //根据类名返回类对象
objc_getClass .pngClass objectMetaClass2 = [[NSObject class]class] ;
//与上面一句不是等效的 这一句只能返回类对象 不能返回元类对象
- 每个类在内存中有且只有一个meta-class对象
-
内存结构和class对象一致 但是用途不一样
meta-class对象 .png
查看是否是meta-class
#import <objc/runtime.h>
BOOL result = class_isMetaClass([NSObject class]);
meta-class的类又是什么呢?
苹果为什么要设计元类这个东西?
完美的闭环
runtime关系图.png
meta-class,就像Class一样,也是一个对象。你依旧可以向它发送消息调用函数,自然的,meta-class也会有一个isa指针指向其所属类。所有的meta-class使用基类的meta-class作为他们的所属类。具体而言,任何NSObject继承体系下的meta-class都使用NSObject的meta-class作为自己所属的类。
根据这个规则,所有的meta-class使用基类的meta-class作为它们的类,而基类的meta-class也是属于它自己,也就是说基类的meta-class的isa指针指向它自己。(译:完美的闭环)
类和meta-class的继承
就像一个类使用super_class指针指向自己的父类一样,meta-class的super_class会指向类的super_class的meta-class。一直追溯到基类的meta-class,它的super_class会指向基类自身。(译:万物归根)
这样一来,整个继承体系中的实例、类和meta-class都派生自继承体系中的基类。对于NSObject继承体系来说,NSObject的实例方法对体系中所有的实例、类和meta-class都是有效的;NSObject的类方法对于体系中所有的类和meta-class都是有效的。
结论:
- meta-class是类对象的类,每个类都有自己单独的meta-class。所有的类对象并不会属于同一个meta-class。
- meta-class要保证类对象具有继承体系中基类的所有实例和类方法,以及继承体系中的所有中间类方法。对于所有NSObject继承体系下的类,
- NSObject的实例方法和协议方法对他们和他们meta-class的对象都要有效。
- 所有的meta-class使用基类的meta-class作为自己的基类,对于顶层基类的meta-class也是一样,只是它指向自己而已。
网友评论