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

Posted MinggeQingchun

tags:

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

苹果官方文档介绍:
Structures and Classes
Choosing Between Structures and Classes

文章中的代码基于swift5.2.4

struct StructTest {
    var name:String
    var age:Int
}

class ClassTest {
    var name:String?
    var age:Int?
}

var structTest = StructTest(name: "", age: 0)
var classTest = ClassTest()

1.struct会自动生成需要的构造方法(constructor),哪个属性没有赋初始值就会生成以哪个属性为参数的构造方法。而class没有,要自己写
2.struct的属性可以不赋初始值,而class的属性必须赋初始值或者设为可选类型,下面也是可以的,区别只是struct自动生成了带参数的init方法

class ScanInfo: NSObject {
    var peripheral: CBPeripheral
    var advertisementData: [String : Any]
    var rssi: NSNumber
    init(peripheral: CBPeripheral, advertisementData: [String : Any], rssi: NSNumber) {
        self.peripheral = peripheral
        self.advertisementData = advertisementData
        self.rssi = rssi
    }
}

2.1 class遵守了协议没有实现方法会报错,而结构体(struct)不会,在正常的项目中struct也会报错,是xcode playground的问题

在这里插入图片描述

在这里插入图片描述

struct StructTest {
    var name:String = "struct1"
    var age:Int = 0
}


class ClassTest {
    var name:String = "class1"
    var age:Int = 0
}

var structTest1 = StructTest()
var structTest2 = structTest1
structTest2.name = "struct2"
print("structTest1.name:\\(structTest1.name)")

var classTest1 = ClassTest()
classTest1.name = "class1"
let classTest2 = classTest1
classTest2.name = "class2"
print("classTest1.name:\\(classTest1.name)")
打印结果:
structTest1.name:struct1
classTest1.name:class2

3.struct是值类型(Value Type),深拷贝。class是引用类型(Reference Type),浅拷贝。


上面代码当classTest2.name的值变了之后,classTest1.name的值也跟着变了。而structTest1.name的值没有跟着structTest2.name的值变化
classTest2前面用let修饰,依然可以改变classTest2.name的值。而要改变structTest2.name的值,structTest2前面必须用var
在这里插入图片描述

3.1 class中可以有单例对象属性,struct中不能有

结构体(struct)和类(class)的区别 单例

4.struct不能继承,class可以继承

在这里插入图片描述

5.NSUserDefaults:Struct 不能被序列化成 NSData 对象,无法归解档

因为归解档的类必须遵守NSCoding协议,struct不能遵守NSCoding协议

参考:
iOS-NSUserDefaults
Swift学习记录 – Swift中throws处理方式
iOS 13归档解档

6.当你的项目的代码是 Swift 和 Objective-C 混合开发时,你会发现在 Objective-C 的代码里无法调用 Swift 的 Struct。因为要在 Objective-C 里调用 Swift 代码的话,对象需要继承于 NSObject。
7.内存分配:struct分配在栈中,class分配在堆中。struct比class更“轻量级”(struct是跑车跑得快,class是SUV可以载更多的人和货物)


知识延伸:“堆”和“栈”的区别,为什么访问struct比class块?
“堆”和“栈”并不是数据结构上的Heap跟Stack,而是程序运行中的不同内存空间。栈是程序启动的时候,系统事先分配的,使用过程中,系统不干预;堆是用的时候才向系统申请的,用完了需要交还,这个申请和交还的过程开销相对就比较大了。

栈是编译时分配空间,而堆是动态分配(运行时分配空间),所以栈的速度快。

从两方面来考虑:
1.分配和释放:堆在分配和释放时都要调用函数(MALLOC,FREE),比如分配时会到堆空间去寻找足够大小的空间(因为多次分配释放后会造成空洞),这些都会花费一定的时间,而栈却不需要这些。
2.访问时间:访问堆的一个具体单元,需要两次访问内存,第一次得取得指针,第二次才是真正得数据,而栈只需访问一次。

参考博客:
Swift — struct与class的差异
Swift 浅谈Struct与Class

相关参考:
查看Xcode所使用Swift的版本

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

swift Class和struct的区别

Swift结构体(Struct)

关于c#的结构体struct与class的区别

C++——class类和struct结构体的唯一区别

C语言中class和struct的区别是啥?

《从零开始学Swift》学习笔记(Day 25)——类和结构体定义