alloc主要创建流程
这里最重要的方法就是这三个:
- cls->instanceSize
- calloc
-
obj->initInstanceIsa
image.png
1、cls->instanceSize
我们要知道,一个对象的创建是需要开辟内存空间的,所以这个方法就是给我们内存开辟空间,以达到创建内存的目的。
2、calloc
这个方法就是根据类的属性,成员变量等创建这个类的实例对象了。
3、obj->initInstanceIsa
我们知道每一个对象都是存在一个isa指针的,这个指针指向这个类的元类,元类的isa指向根元类,根元类的isa指向NSObject。所以每一个类都存在这个isa指针,这个方法就是创建isa指针的。
对象内存对齐原则
首先我们创建一个类Person,给这个类添加了三个属性age,name和height。
给他们赋值:
- (void)viewDidLoad {
[super viewDidLoad];
LGPerson *p = [LGPerson alloc];
p.age = 18;
p.name = @"cooci";
p.height = 185;
NSLog(@"%zu",class_getInstanceSize([p class])); // 8 --- 16
NSLog(@"%zu",malloc_size((__bridge const void *)(p))); // 16
// 系统 内存对齐 --- ISA 8 age 4 (int 剩 4) name(8)
// 8 算法
// 16 优化
// 对象内存分配
// isa -- age -- height -- name : 8 + 4 + 4 + 8 = 24 ---- 32
// isa -- age -- name -- height : 8 + 8 + 8 + 8 = 32 ---- 32
}
通过测试打印得知:
- isa是一个指针,占8字节
- age和height是int类型,占4个字节
- name是字符串指针,占8个字节
总共占用内存字节数:8+4+4+8=24;
但是系统分配内存在arm64下是16字节对齐的,所以会进去位移操作,最终这个对象占用了内存32个字节。也就是大于24的最小16的倍数。
image.png
内存位移技巧
创建对象,分配内存的时候是8字节对齐的。
比如person中的age是4个字节,如果后面跟着的是name为八个字节,要保证内存8字节对齐,那么age后面会跟着空出4字节来,让name从下一个8字节位置开始。
这样的好处是方便读取,不容易出错,也为了效率。
同样的,当对象创建完成的时候,系统分配内存也是保证16字节对齐的。
那么8字节和16字节是怎样完成的呢?
加入当前字节数为a:
8字节对齐:a + 7 << 3 >> 3。如果 a==5,那么结果为16
16字节对齐:a + 15 << 4 >> 4。如果a==5,那么结果为32
网友评论