iOS中对象的本质

首先看三个面试题,本片文章的核心。
1.一个NSObject对象占有多少内存?
2.对象的isa指针的指向哪里?
3.OC的类信息存放在哪里?

一.对象的大小

对象的本质其实是结构体,计算结构体大小(对象实际大小),因为内存对齐 ,8的倍数 class_getInstanceSize / sizeof
系统实际分配对象内存,内存对齐,16的倍数。malloc_size

NSLog(@"-------%zu",class_getInstanceSize([[NSObject alloc] class]));
NSLog(@"-------%zu",sizeof([[NSObject alloc] class]));
NSLog(@"-------%zu",malloc_size((__bridge const void *)([NSObject alloc])));
2021-02-25 17:31:36.444104+0800 Interview01-OC对象的本质[45350:1506255] -------8
2021-02-25 17:31:36.444380+0800 Interview01-OC对象的本质[45350:1506255] -------8
2021-02-25 17:31:36.444419+0800 Interview01-OC对象的本质[45350:1506255] -------16

内存对齐: 1. 实际分配内存大小为16的倍数 2.结构体实际占用内存大小必须是最大成员大小的倍数

二.对象的种类

Instance实例对象 (存储 isa指针与其他成员变量)

获取实例对象
 // instance对象,实例对象
NSObject *object1 = [[NSObject alloc] init];

Class类对象(存储isa指针,superclass指针,类的属性信息(@property),类的对象方法信息(instance method),类的协议信息(protocol),类的成员变量信息(ivar))

获取类对象
// class对象,类对象
// class方法返回的一直是class对象,类对象
Class objectClass1 = [object1 class];
Class objectClass2 = [object2 class];
Class objectClass3 = object_getClass(object1);
Class objectClass4 = object_getClass(object2);
Class objectClass5 = [NSObject class];

在源码中的结构关系为

图片.png

meta-class元类对象(包含isa指针,superclass指针,类的类方法信息(class method),class_ismetaclass 用来判断是否为元类对象)

获取 meta-class对象,元类对象
// 将类对象当做参数传入,获得元类对象
Class objectMetaClass = object_getClass(objectClass5/*objectClass5 为类对象*/);
三.isa与superclass

首先,我们先放一张非常经典的图。


图片.png

结合图片理解为:
isa的指向对象的 isa 指向 ; 类的 isa 指向 元类,元类的 isa 指向 根元类(基类),根元类(基类)的 isa 指向 自己

类的superclass的指向的 superclass 指向父类, 父类的 superclass 指向 根类 ,根类的superclass 指向 nil

元类的superclass的指向元类的 superclass 指向 父类的元类,父元类的 superclass 指向 根元类, 根元类的 superclass 指向 根类, 根类的 superclass 指向nil

例1:

 Person *p = [[Person alloc] init];

如何获取到对象P的isa指向的类:

class q == object_getClass(p)

根据对象P的isa指向类对象的isa获取到元类

object_getClass(q)

class_isMetaClass() //可以用来检测是否为元类
class_isMetaClass(object_getClass([Person class]))

例2
有如下图关系Student类与Person类
isa指针的指向关系

图片.png

superclass指针指向关系为

图片.png

student与person在总结图中的对象关系为

图片.png

实例对象调用对象方法的流程

类对象调用类方法的流程

图片.png

1.一个NSObject对象占有多少内存?

  • 系统分配了16个字节给NSObject对象(通过malloc_size函数获得)
  • 但是NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInstanceSize函数获得)

2.对象的isa指针的指向哪里?

  • instance对象的isa指向class对象
  • class对象的isa指向meta-class对象
  • meta-class对象的isa指向基类的meta-class对象

3.OC的类信息存放在哪里?

  • 对象方法,属性,成员变量,协议信息,存放在class对象中
  • 类方法存放在meta-class对象中
  • 成员变量的具体值存放在instance对象中

你可能感兴趣的:(iOS中对象的本质)