一.枚举
关联值:成员值将其他类型的值关联存储在一起。会影响枚举变量的内存分布。原始值:预先设置的值是原始值,int或者string会自动设置隐式原始值,原始值不占用成员枚举变量的内存
枚举变量的内存分布:bool占1个字节,float占4个,int占8个字节,double占8个,string占16个字节。当枚举成员变量只有一个时,无字节来标记成员值。当枚举成员变量有多个时,以最大需求容量的枚举值来计算内存大小,并加上标记字节作为实际占用字节,以类型的对齐标准来计算分配的内存。特殊情况,当关联值容量小于等于3时,若bool在末尾,将标记字节内嵌于bool字节中,否则bool以类型标准对齐填满。当关联值内容大于4时,若bool在末尾,将标记字节内嵌于bool字节中,若bool在第3位到倒数第二位之间,将标记字节内嵌于bool字节中,并bool以类型标准对齐填满,若在前两位,按默认方式计算。
与oc的枚举值不同,oc的枚举相当于一个整型,而swift的枚举适用于各种类型,且通过元组关联存储其他类型,并且还适用协议,方法等,本质上,枚举相当于某一时刻只有一个变量,而结构体和类同时拥有多个属性。
二.struct和class
1.初始化:struct会生成一个或者多个初始化器,保证成员都有初始值,但如果自定义初始化器,则编译器不会再生成,class一般情况下是不会生成初始化器。2.struct是值类型 class是引用类型。struct在复制或传参时,是拷贝内容,class是拷贝内存地址;struct内存结构根据成员变量累加,在bool为中间位置时,根据类型标准填充,class的内存大小需要通过runtime的方法才能计算出内存大小,首先要添加16字节描述信息和引用计数,剩余字节数按照默认方式计算。3.struct在自身的实力方法修改属性时需要加mutating。4.struct不能被继承,class可以。
2.属性。分为存储属性和计算属性,枚举不能定义存储属性,只能叫枚举变量,区别是存储属性必须在初始化类或者创建实例时附值初值。此外,延迟存储属性在第一次用到时才会初始化,除开延迟计算属性的存储属性可以设置属性观察器。属性观察器在值改变时主动出发,计算属性在取值或者设置时手动调用。
3.方法。实例方法和类型方法。实例方法只供实例调用,类型方法供类调用。值类型的实力方法不能改变他的存储属性,需要通过mutating修改传入inout通过地址引用来修改。
4.类的初始化器。分为指定初始化器和便捷初始化器。指定初始化器只能调用父类的初始化器,但不能调用本身的初始化器,调用之前必须完成当前类属性的附值,便捷初始化器必须调用指定初始化器。指定初始化器存在继承,即可以重新加上override,便捷初始化器不存在重写,即不需要加override。
5.类的继承。属性和方法按类型分也可以分为实例属性和类型属性。实例属性都可以重新,类型属性可用static和class修饰,static修饰的不可重写,class修饰的可以重写。而方法的重写机制等同类型属性。注:class不可修饰存储类型属性。finnal修饰时均不可以重写
6.类类型的闭包。函数和他引用的外部变量或者常量组成,相当于类对象,存于堆中,引用的变量相当于存储属性,函数相当于方法。自动闭包:在函数参数为函数调用时,会出现函数体内被先调用,想要做成某些情况不走他,避免资源浪费,可讲函数的形参设置为函数,可以起到延迟调用的效果,但他无法传入参数,此时引入自动闭包,他相当于通过大括号将内容传进来,同时也起到了延迟调用的效果。
class_getInstanceSize计算实际占用内容。Mems.size分配的内存以16对齐
属性:存储属性和计算属性。存储属性可分为延迟存储和非延迟存储,也可分为存储实例属性和存储类型属性;计算属性可分为计算实例属性和计算类型属性。方法也可分为实例方法和类型方法。
针对struct:他的方法不能改变属性。必须加mutating。
针对class类型的重写:所有的实例属性和实例方法都可以直接重写,只是类型属性和类型方法中,只有class修饰的可重新,而staic修饰的不行(除存储类型属性,因为整个内存中只占份)。final禁止重写
