前言
我们知道一个NSObject对象创建的时候系统分配了16个字节,实际使用的只有8个字节,可是里面要是添加了属性之后呢,是多少呢,又是按照什么原则,所以这些是本章需要探索的重点,另外还有结构体,文章末尾也会为大家提供源码。
探索
一、类
1.创建一个空的iOS项目,然后创建一个类如下:
@interface HXPerson: NSObject
//对象占了8字节(0-7)
@property (nonatomic, copy) NSString *name; // 8 (8,15)
@property (nonatomic, copy) NSString *nickName; //8 (16,23)
@property (nonatomic, assign) int age; //4 (24,27)
@property (nonatomic, assign) long height; //8 因为28不是8的整数倍,所以从32开始算起
//(32,39)因为实际使用的内存要是8的整数倍,所以实际使用的就是40字节,系统分配的要是16的整数倍,所以是48,为什么是16的整数倍呢,具体可以看最新的oc源码
//@property (nonatomic) char c1;
//@property (nonatomic) char c2;
@end
@implementation HXPerson
@end
2.在main函数中调用,需要导入头文件#import <objc/runtime.h>
#import <malloc/malloc.h>,否则后面两句会报错
HXPerson* person = [HXPerson alloc];
person.name =@"hanxiao";
person.nickName =@"hh";
person.age =18;
NSLog(@"%lu-%lu",class_getInstanceSize([HXPerson class]),malloc_size((__bridge const void *)(person)));
二、结构体
1.创建结构体,如下:
struct HXStruct1 {
double a; // 8 (0-7)
char b; // 1 [8 1] (8)
// 4 [9 4] 9 10 11 12
//因为9不是4的整数倍,所以要从12开始算起,也就是12,13,14,15
int c;
short d; // 2 [16 2] (16 17)
}struct1;
// 内部需要的大小为: 17
// 最大属性 : 8
// 结构体整数倍: 24
struct HXStruct2 {
double a; //8 (0-7)
int b; //4 (8 9 10 11)
char c; //1 (12)
short d; //2 13 (14 15) - 16
}struct2;
// 15 -> 16
struct HXStruct3{
double a; //8 (0-7)
int b; //4 (8 9 10 11)
char c; //1 (12)
short d; //2 13 (14 15) - 16
NSString* (*getName)(void);//8 (16,23)-24
struct HXStruct1 hxSc;
}struct3;
struct HXStruct4{
//函数占8个字节
void(*initWithOptions)(NSDictionary*);//8(0-7)
NSString*(*getDeviceInfo)(void);//8(8-15)
NSString*(*getInitStatus)(void);//8(16-23)
NSDictionary*(*getConfigInfo)(void);//8(24,31)
}struct4;
2.在main函数中调用
NSLog(@"%lu-%lu",sizeof(struct1),sizeof(struct3));
我们发现结构体里面嵌套结构体依然满足原则,只需要耐心数就行了。
总结
内存对齐原则:
1:数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第
⼀个数据成员放在offset为0的地⽅,以后每个数据成员存储的起始位置要
从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,
结构体等)的整数倍开始(⽐如int为4字节,则要从4的整数倍地址开始存
储。 min(当前开始的位置m n) m = 9 n = 4
9 10 11 12
2:结构体作为成员:如果⼀个结构⾥有某些结构体成员,则结构体成员要从
其内部最⼤元素⼤⼩的整数倍地址开始存储.(struct a⾥存有struct b,b
⾥有char,int ,double等元素,那b应该从8的整数倍开始存储.)
3:收尾⼯作:结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤
成员的整数倍.不⾜的要补⻬。
一句话,就是实际使用的内存是8的倍数,系统分配的内存是16的倍数(为了安全,防止读到其他内存)。
内存占用图最后提供下源码地址,喜欢的麻烦点个赞,谢谢!
网友评论