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

50 篇文章 0 订阅

返回上级目录:swift,oc语法(苹果文档)和对比

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

文章中的代码基于swift5.2.4

1,2

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没有,要自己写

  • 貌似如果你自己写了,系统就不会给你生成了

Memberwise Initializers for Structure Types - apple developer

请添加图片描述

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的问题

在这里插入图片描述
在这里插入图片描述

3

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

4
在这里插入图片描述

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

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

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

5
在这里插入图片描述

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.class像oc的类一样,可以用kvo,kvc,runtime的相关方法,适用runtime系统。这些struct都不具备。

请添加图片描述
请添加图片描述
请添加图片描述

7.1 struct也不能遵守NSObjectProtocol协议

  • Non-class type ‘SwiftStruct’ cannot conform to class protocol ‘NSObjectProtocol’
  • Cannot declare conformance to ‘NSObjectProtocol’ in Swift; ‘SwiftClass’ should inherit ‘NSObject’ instead
    请添加图片描述
    请添加图片描述

8.内存分配:struct分配在栈中,class分配在堆中。struct比class更“轻量级”(struct是跑车跑得快,class是SUV可以载更多的人和货物)

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

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

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

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

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值