前言:
仅为视频学习笔记
MemoryLayout
MemoryLayout怎么用呢?
★可以使用MemoryLayout获取数据类型占用的内存大小
MemoryLayout是可以写成泛型。
var age = 10
那么,我们想知道age这个变量占用多少内存,那么怎么办呢?这个用法其实也非常简单,如下:
MemoryLayout.size(ofValue: age) // 8 MemoryLayout.stride(ofValue: age) // 8 MemoryLayout.alignment(ofValue: age) // 8
我们会发现,打印出来的跟 例-1所打印出来的一样,因为age它就是Int类型。所以 例-1跟上面代码,打印出来是一样的,百分百是等价的。
看一下size和stride有什么区别?要看出它们的区别,当然要搞些不同的类型才能看出来。比如说,就拿我们这个枚举来说,你也许很好奇,这个枚举变量,到底占用多少内存呢?
Password是密码,一个是数字密码,一个就是另外一种密码。
swift编码规范里面,枚举的类型首字母,是大写的,采用驼峰标示,它里面的所有成员,建议小写开头。
var pwd = Password.number(5, 6, 4, 7) // 占用32字节 pwd = .other
比如,上面代码,我们猜测一下, 第一行,和第二行,各占多少内存呢? 也就是,我想知道 pwd 这个变量,编译器给它分配多少个内存呢?
首先,先下一个定论,你看,我先定义了一个pwd变量,那么这个变量呢?一个是赋得值是 Password.number(5, 6, 4, 7),之前说过,像这种关联值(5, 6, 4, 7) 是直接存储在pwd这个变量里面,所以说你这个变量内存肯定装得下这4个(5, 6, 4, 7) ,那么每一个Int类型占8个字节,那你4个,4x8 = 32 ,32个字节。所以pwd 这个变量至少是32个字节。
那么,现在我假定var pwd = Password.number(5, 6, 4, 7)是32个字节 ,那么pwd = .other这个位置呢?思考一下,肯定是你 var pwd = Password.number(5, 6, 4, 7)这行占用了多少字节pwd = .other这行占用多少字节。也就是说,var pwd = Password.number(5, 6, 4, 7)是32个字节,那么到后边的时候仍然是32个字节。只是用32个字节存储.other这个家伙而已。
不可能说,根据我赋的值不同,到时候我动态改变内存,这样多麻烦。
变量内存已经开辟了32个字节,上面占用32个字节,下面也占用32个字节,变量内存是不会动态改变的,没用也要占用在内存里面。
因为,只要你pwd是Password类型的,那么它的大小已经固定了,就是这么大。但是,你以后是存储number(Int,Int,Int,Int)这个 还是 other取决于你自己。
下面我们看究竟占多少呢?
如上面方法,得知,size和stride是不一样的。一个是33,一个是40,到底是哪个才对呢?
先说一下size和stride有什么区别:
stride这个家伙是范围的意思,打印出来这个40是什么意思呢,这个就是这个变量实际占用的空间大小,也就是说这个就是它真正的所要占用的空间大小。
size是什么呢? size是实际用到的空间大小,也就是说,实际可能用到的大小。相当于就是有7个字节是浪费掉的。有7个字节你是永远用不到的。
再来看alignment我们这个内存对齐参数,很明显是8。那就是意味着,你最后占用的内存大小肯定是8的倍数,所以说stride这个家伙,系统分配给它的就是40个字节,这40个字节,其中有33个字节,是拿来实际放东西的,那么33个字节,大家可以想得到分别拿来放什么呢?其中肯定有32个字节,是用来放(Int,Int,Int,Int)这个家伙,那么最后一个字节,应该是拿来放other这个家伙。
40这个内存不是32 + 8, 也就是说,我们最终算出来的这个40,不是32 + 8。
这个40是怎么来的?首先你先存储这4个家伙(Int,Int,Int,Int) ,那你肯定要32个字节,other这个家伙其实用1个字节就搞定了,所以你真正要用到的就是33个字节,但是由于我们这个alignment内存对齐呢,是8,所以你要保证最终分配给你的内存大小是8的倍数,所以说33不够,要补齐为40。所以,最终分给你的是40。