OC对象一共分为3中:
- instance对象(实例对象)
- class对象(类对象)
- meta-class对象(元类对象)
一: instance对象
instance对象就是通过类alloc出来的对象,每次调用alloc都会产生新的instance对象.
之前我们分析的就是 instance 对象,instance 对象在内存中存储的信息主要包括:
1: isa指针
2: 其他成员变量
二: class 对象
每个类在内存中有且只有一个类对象,他们在内存中存储的信息主要包括:
1: isa 指针
2: superclass 指针
3: 类的属性信息 (@property),类的对象方法信息 (instance method)
4: 类的协议信息 (@protocol),类的成员变量信息 (ivar)
获取一个对象的类信息,有三种方法:
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person = [[Person alloc]init];
//方法一
Class person1 = object_getClass(person);
//方法二
Class person2 = [Person class];
//方法三
Class person3 = [person class];
NSLog(@"%p , %p , %p",person1,person2,person3);
}
return 0;
}
=========================== 打印如下=================
2019-02-25 15:35:49.432933+0800 OC对象的分类_01[3342:254486] 0x1000011c8 , 0x1000011c8 , 0x1000011c8
可以看到三个对象的地址都是相同的.
三: meta-class 对象 (元类对象)
每个类中有且只有一个元类对象,同样通过object_getClass ()
方法获得,只不过要把类对象当做参数传递进去.
meta-class 和 class 对象的内存结构是一样的,都是class
类型,但是用途不一样,在内存中存储的信息主要包括:
1: isa 指针
2: superclass 指针
3: 类的类方法信息 (class method)
注意,meta-class 和 类对象的结构是一样的,也就是说 meta-class 对象中也有属性信息,协议信息,成员变量信息,实例方法信息,只不过在 meta-class 中,这些信息都是null.如图所示:
objc_getClass() , object_getClass() , class()
方法区别:
-
object_getClass()
可以通过 runtime 源码看一下object_getClass()
的底层:
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
发现object_getClass()
底层调用的是getIsa()
,而实例对象的 isa 指针指向类对象,类对象的 isa 指针指向元类对象,元类对象的 isa 指针指向基类的元类对象.
结论:
1: 如果传入的是 instance 对象,返回 class 对象.
2: 如果传入 class 对象 返回 meta-class 对象.
3: 如果传入 meta-class 对象,返回 NSObject (基类)的 meta-class 对象.
-
objc_getClass()
传入一个字符串类名,返回对应的类对象 -
class()
返回类对象.