1. 简单概述
万物皆对象,OC 对象可以分为以下三类:
1、instance 对象 - 实例对象:
存放 isa、成员变量值;
2、class 对象 - 类对象;
存放 isa 指针、superclass 指针、类的属性信息(名称)、对象方法、协议、成员变量等;
3、meta-class 对象 - 元类对象;
isa 指正、类方法等。
2. instance对象(实例对象)
instance 对象就是通过类 alloc 出来的对象,每次调用 alloc 都会产生新的 instance 对象:
Person *person1 = [[Person alloc] init];
Person *person2 = [[Person alloc] init];
person1、person2 是 Person 的 instance 对象(实例对象) 是两个不同的对象。

instance 对象在内存中存储的信息包括:
-
isa 指针;
-
其他成员变量。
3. class对象 (类对象)
一个类的类对象可以通过以下方式获取:
Person *person1 = [[Person alloc] init];
Person *person2 = [[Person alloc] init];
// Person 对象方法
Class class1= [person1 class];
Class class2= [person2 class];
// Person 类方法
Class class3= [Person class];
// Runtime 方法:参数 -> 实例对象
Class class4= object_getClass(person1);
Class class5= object_getClass(person2);
NSLog(@"class1: %p", class1);
NSLog(@"class2: %p", class2);
NSLog(@"class3: %p", class3);
NSLog(@"class4: %p", class4);
NSLog(@"class5: %p", class5);
日志输出:
OC 对象的分类_Test01[97653:2509948] class1: 0x100001248
OC 对象的分类_Test01[97653:2509948] class2: 0x100001248
OC 对象的分类_Test01[97653:2509948] class3: 0x100001248
OC 对象的分类_Test01[97653:2509948] class4: 0x100001248
OC 对象的分类_Test01[97653:2509948] class5: 0x100001248
上述 5 个类对象地址均相同,它们是同一个对象。
所以:每个类在内存中有且只有一个类对象。
类对象在内存中存储的信息主要包括
- isa 指针
- superclass 指针
- 类的属性信息(@property)
- 类的对象方法信息(instance method)
- 类的协议信息(protocol)
- 类的成员变量信息(ivar) - 类型之类的,不存放具体值。
上述方法分析: class 方法: 实例对象方法:- (Class)class
- (Class)class {
return object_getClass(self);
}
通过调用object_getClass()方法,object_getClass()函数:
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
返回 isa 指针所指向的对象(实例对象的 isa 指向类对象;class 对象的 isa 指向元类对象;元类对象的 isa 指向 基类的元类对象);
类对象方法:+ (Class)class
+ (Class)class {
return self;
}
直接返回 self;
4. meta-class对象(元类对象)
元类对象可以通过 runtime 的 object_getClass(),参数传入类对象(如果传实例对象的话得到的是类对象)
Class meta_class= object_getClass([Person class]);
NSLog(@"meta_class: %p", meta_class);
画外音:还有一个名字同 object_getClass 很像的函数 objc_getClass,该方法的注释大概意思:根据传入字符串,返回一个对应名称的类(即:类对象)。
/***********************************************************************
* objc_getClass. Return the id of the named class. If the class does
* not exist, call _objc_classLoader and then objc_classHandler, either of
* which may create a new class.
* Warning: doesn't work if aClassName is the name of a posed-for class's isa!
**********************************************************************/
Class objc_getClass(const char *aClassName)
{
if (!aClassName) return Nil;
// NO unconnected, YES class handler
return look_up_class(aClassName, NO, YES);
}
元类对象也是类对象,所以其内存结构也是一样的,用途不一样而已:
每个类在内存中有且只有一个 meta-class 对象;
meta-class对象,在内存中存储的信息主要包括
- isa指针
- superclass指针
- 类的类方法信息(class method)
- ......
Runtime API 中还提供了一个判断是否为元类对象的方法 class_isMetaClass:
Class meta_class= object_getClass([Person class]);
BOOL isMeta_class = class_isMetaClass(meta_class);
NSLog(@"isMeta_class: %d", isMeta_class);
输出:
isMeta_class: 1