类与结构体在let上的区别
在var修饰的情况下,结构体是进行一个copy one write的深拷贝,而类在没有进行深拷贝的情况下,普通的赋值操作等等,只是进行个指针复制操作
只写结果吧,在let情况下,类和结构体都不能重新赋值,但类的成员变量可以修改,结构体不行
原因是,let是决定的当前的内存不能修改,所以类是指针不能修改,但指针指向的地址是可以修改的,所以它的成员变量可以修改,如果成员是常量那也不可以,但结构体的变量就是它的存储地址,所以啥都不让改
类的内存对齐
图中的类,应该是类信息(8) + 引用计数(8) + x(8) + y(8) + isDir(1) = 32个字节,加上内存对齐是40个字节,但实际输出的是48个字节
再看一个
这个类应该是8 + 8 + 1 + 1 = 20内存对齐来说是24,但实际分配的是32,所以可以看出swift的堆空间分配是按16的倍数来的,所谓buffersize的基础是16个字节
嵌套类型
使用方式大约如图,其实就是个语法,把枚举写入结构体形成嵌套,一般可以用来在内部定义可选性,也可以直接访问内部的枚举,就像有时候定义在内部的枚举也希望在其它地方使用,而不是重新定义一个
方法
一般来说定义在全局或者外部的称为函数,而写在结构体,枚举,类里面的叫方法,其实是同一个东西
方法的位置以及程序的内存基本划分
方法和函数都一样,不管写哪最终都是放在代码段的,不管是类里面的方法,还是全局的函数
代码如图,打上断点后可以看到二进制里面callq的函数内存地址
全局函数ptr地址是0x100001e40
ptr1的地址大概是0x1000023a0,比这个值要小点
结构体得方法是0X100002a40
大概可以看出这三个函数其实属于同一个地址段,但单看这一个好像不是很明显
把上面打印出来的东西排个序
代码段:
ptr:0x100001e40 ptr1:0x1000023a0 ptr2:0X100002a40
全局段(数据段):
全局变量val地址: 0x000000010000c3c0
成员变量name地址: 0x000000010000c3d0
成员变量age地址: 0x000000010000c3e0
因为枚举是在全局区定义的,所以枚举的地址在全局段
堆区:
成员变量x地址: 0x00000001010084a0
成员变量y地址: 0x00000001010084a8
栈区:
局部变量localVar地址: 0x00007ffeefbff398
局部变量localVar1地址: 0x00007ffeefbff388
从代码来看这些变量常量定义的地址不一样,既不是按照函数的执行顺序划分,也不是按照位置划分,而是按类型划分的,从小到大分别是代码段,全局段(数据段),堆,栈