Swift 结构体和类的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift 结构体和类的区别相关的知识,希望对你有一定的参考价值。

参考技术A 1.结构体属于值类型,类属于引用类型;
2.值类型赋值给let var 或者函数传参的时候完,全是深拷贝;
3.引用类型赋值给let var 或者函数传参的时候完,是将内存地址拷贝一份,属于浅拷贝;
4.结构体属于值类型,标准库中的结构体采用copy on write策略,优化效率;
5.结构体不可以继承,可以继承;
6.都可以实现方法,都可以添加计算属性和存储属性,都支持属性监听,都支持扩展.都可以遵守协议.结构体的方法修改属性的时候需要用@mutating修饰(枚举也需要);
7.结构体初始化的时候必须要给属性赋值,来决定结构体在内存中的布局.Class初始化的时候可以暂时不用赋值;
8.结构体声明属性的时候不需要赋值,class 声明属性的时候必须赋值或者包装成Optional;
9.required关键字只支持Class, Class可以用static和Class 关键字修饰静态方法;Struct 只能用Static 修饰;

初始化required修饰的指定初始化器,子类必须要实现同样的指定初始化器,要么继承要么在子中用required重写父类的指定初始化器;
init?可失败初始化器;
指定初始化器;
可选初始化器;

willset\didset

都属于实例属性:只能通过实力去访问
lazy var 是一种延迟的存储类型.存储属性存储在对象或者结构体的内存中,计算属性不占用结构体或者对象的属性.

整个程序运行期,只有一份比如单例;
存储类型属性:
计算类型属性:

非lazy的var的存储属性,计算属性不能设置属性观察器;但是在初始化的时候设置不会触发(包括在init和定义的时候赋值)

传入存储属性:传入结构体或者对象的地址,然后找到存储属性的值,直接访问或者修改;
传入添加了属性观察器的存储属性:传入结构体或者对象的地址,然后在函数内部开辟一段局部变量作为临时存储,并把这个临时地址传入set方法内重新设置,在此之前会调用willset方法,设置完调用didiset方法;
传入计算属性:传入结构体或者对象的地址,然后先调用计算属性的get方法,然后在函数内部开辟一段局部变量作为临时存储,并把这个临时地址传入set方法内重新设置.

类方法和实例方法 也是通过static修饰来区别.用法和OC以一样

使用subscript可以给任何类型(枚举、结构体、类)增加下标功能;subscript的语法类似于实例方法,计算属性,本质就是方法(函数);
不同点在于结构体中的subscript必须实现set方法才能通过p[0] = 10修改值,但是Class的只需要实现get方法就可以实现p[0] = 10赋值,原因是前者是值拷贝,后者是引用拷贝.

值类型不支持继承,只有类支持继承;
swift不像OC任何类都要继承自某一个类;
重写方法重写下标:calss 修饰的类型方法可以通过override重写,但是static修饰的则不可被重写
重写实例属性:可以把父类的存储属性重写为计算属性,只能重写var属性,重写之后权限大于等于夫类
重写类型属性::calss 修饰的计算属性可以通过override重写,但是static修饰的则不可被重写. 存储属性不可以被calass修饰
属性观察期:可以在子类中为计算属性和存储属性添加属性观察,
不希望继承重写用final修饰
9.1内存结构
前八个字节存放类的基本信息,通过八个字节指向堆空间的一段内存,可以找到方法实现。接下来的八个字节存放类的引用计数。再往后是类的属性的内存地址。

OC:runtime
swift:通过前八个字节去查找堆上方法的实现

Self.Type/Perosn.self是类的原类其实就是类的对象的前八个字节的内容,通过元类型可以动态创建类的实例;
协议:可以被类、枚举、结构体遵守;可以继承,可以添加属性和方法,可以定义初始化器,协议约定的方法属性必须要实现,协议可以通过 & 组合作为参数的约束条件,类似于 ;
Any\Anyobject\Anyclass:任意类型,任意对象,任意元类对象

以上是关于Swift 结构体和类的区别的主要内容,如果未能解决你的问题,请参考以下文章

Swift-Class和Struct的区别(结构体和类的区别)

结构体和类的区别,联系

结构体和类的区别?

结构体和类的唯一区别就是类函数没有加说明是私有而结构体函数是公有

swift结构体和类属性-005-swift类结构体基本属性

结构和类的区别及结构的使用