iOS 内存分配原则介绍2/2

264 阅读3分钟

这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

上一篇讲了内存分配原则:iOS 内存分配原则介绍1/2

也用了结构体进行了举例验证了内存分配原则,但是细心的同学如果用类去验证内存分配原则就会发现行不通。。。这是为什么呢?今天我们就来深入浅出一下~

首先还是把内存分配原则贴一下:

ios 内存分配原则

  1. 数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第⼀个数据成员放在offset为0的地⽅,以后每个数据成员存储的起始位置要从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,结构体等)的整数倍开始(⽐如int为4字节,则要从4的整数倍地址开始存储。

  2. 结构体作为成员:如果⼀个结构⾥有某些结构体成员,则结构体成员要从其内部最⼤元素⼤⼩的整数倍地址开始存储.(struct a⾥存有struct b,b⾥有char,int ,double等元素,那b应该从8的整数倍开始存储.)

  3. 收尾⼯作:结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤成员的整数倍.不⾜的要补⻬。

然后我用了结构体进行了说明:

image.png

下面把结构体中的成员再搬到类中:

然后看下内存大小

@interface FirstStruct : NSObject
@property (nonatomic, assign) char a; //1字节
@property (nonatomic, assign) double b; //8字节
@property (nonatomic, assign) int c; //4字节
@property (nonatomic, assign) short d; //2字节
@end

@interface SecondStruct : NSObject
@property (nonatomic, assign) double b; //8字节
@property (nonatomic, assign) int c; //4字节
@property (nonatomic, assign) char a; //1字节
@property (nonatomic, assign) short d; //2字节
@end

FirstStruct *first = [FirstStruct new];
first.a = 'a';
first.b = 12.23;
first.c = 13;
first.d = 24;
NSLog(@"firstStruct instance size:%lu alloc size:%lu",class_getInstanceSize(first.class), malloc_size((__bridge const void *)(first)));

SecondStruct *second = [SecondStruct new];
second.a = 'a';
second.b = 12.23;
second.c = 13;
second.d = 24;
NSLog(@"secondStruct instance size:%lu alloc size:%lu",class_getInstanceSize(second.class), malloc_size((__bridge const void *)(second)));

打印结果:

2021-11-07 17:21:06.990866+0800 testOC[85185:17320090] firstStruct instance size:24 alloc size:32

2021-11-07 17:21:06.990899+0800 testOC[85185:17320090] secondStruct instance size:24 alloc size:32

为什么和结构体中同样的顺序,大小却不一样呢?

还有一点需要知道,类是有一个isa指针在父类NSObject里面,而父类属性肯定是在最前面的,那为什么在相比于结构体多了isa指针结果还是这样呢?

image.png

哈哈,,让我来告诉你们吧~~~

  1. 首先,class_getInstanceSize 方法获取的是对象所需要的内存大小,malloc_size方法获取的是系统最终分配的内存大小,为甚么两个最终结果不一样呢,这个最后再说,这里先看class_getInstanceSize方法获取的大小是怎么来的

  2. class_getInstanceSize 获取的大小和纯结构体的大小不一致的原因有两方面

    • 1.类多了一个isa指针
    • 2.在从类属性列表到类结构体的过程中系统做了优化,系统会根据内存分配原则调整结构体中元素的顺序,以便将内存占用压缩到最小

怎么说呢,简单说就是系统根据内存分配原则优化了类的结构体,使这个类在经过内存分配原则后能占用尽量少的内存

有些同学可能不信。。。。

不信的同学可以走了。。。。

哈哈。。。

怎么证明这个事情呢?

有点口渴了,下篇在介绍吧?好不?