千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:成都千锋IT培训  >  技术干货  >  swift中结构体和类的区别(值类型和引用类型的区别)?

swift中结构体和类的区别(值类型和引用类型的区别)?

来源:千锋教育
发布人:xqq
时间: 2023-10-17 14:43:02

一、swift中结构体和类的区别

类是引用类型,存储在堆区;结构体是值类型,存储在栈区。类有继承特性;结构体没有。类实例可以被多次引用,有引用计数。结构体没有引用计数,赋值都是值拷贝。类有反初始化器(deinit)来释放资源。类型转换允许你在运行时检查和解释一个类实例的类型。

值类型 vs 引用类型

结构体是值类型,实际上,Swift 中所有的基本类型:整数,浮点数,布尔量,字符串,数组和字典,还有枚举,都是值类型,并且都以结构体的形式在后台实现。

这意味着字符串,数组和字典在被赋值到一个新的常量或变量,或者它被传递到一个函数或方法中的时候,其实是传递了值的拷贝。这不同于 OC 的 NSString,NSArray 和 NSDictionary,他们是类,属于引用类型,赋值和传递都是引用。

值类型存储的是值,赋值时都是进行值拷贝,相互之间不会影响。而引用类型存储的是对象的内存地址,赋值时拷贝指针,都是指向同一个对象,即同一块内存空间。

1、结构体是值类型

swift

复制代码

struct Book {

    var name: String

    var high: Int

    func turnToPage(page:Int) {

        print(“turn to page \(page)”)

    }

}

var s = Book(name: “程序员的自我修养”, high: 8)

var s1 = s

s1.high = 10

print(s.high, s1.high) // 8 10

这段代码中初始化结构体high为18,赋值给s1时拷贝整个结构体,相当于s1是一个新的结构体,修改s1的high为10后,s的age仍然是8,s和s1互不影响。

通过 lldb 调试, 也能够看出 s 和 s1 是不同的结构体. 一个在 0x100008080, 一个在 0x100008098.

swift

复制代码

(lldb) frame variable -L s

0x0000000100008080: (SwiftTest.Book) s = {

0x0000000100008080:   name = “程序员的自我修养”

0x0000000100008090:   high = 8

}

(lldb) frame variable -L s1

0x0000000100008098: (SwiftTest.Book) s1 = {

0x0000000100008098:   name = “程序员的自我修养”

0x00000001000080a8:   high = 10

}

2、类是引用类型

swift

复制代码

class Person {

    var age: Int = 22

    var name: String?

    init(_ age: Int, _ name: String) {

        self.age = age

        self.name = name

    }

    func eat(food:String) {

        print(“eat \(food)”)

    }

    func jump() {

        print(“jump”)

    }

}

var c = Person(22, “jack”)

var c1 = c

c1.age = 30

print(c.age, c1.age) // 30 30

如果是类,c1=c的时候拷贝指针,产生了一个新的引用,但都指向同一个对象,修改c1的age为30后,c的age也会变成30。

swift

复制代码

(lldb) frame variable -L c

scalar: (SwiftTest.Person) c = 0x0000000100679af0 {

0x0000000100679b00:   age = 30

0x0000000100679b08:   name = “jack”

}

(lldb) frame variable -L c1

scalar: (SwiftTest.Person) c1 = 0x0000000100679af0 {

0x0000000100679b00:   age = 30

0x0000000100679b08:   name = “jack”

}

(lldb) cat address 0x0000000100679af0

address:0x0000000100679af0, (String) $R1 = “0x100679af0 heap pointer, (0x30 bytes), zone: 0x7fff8076a000”

通过lldb调试,发现类的实例 c 和 c1 实际上是同一个对象, 再通过自定义命令 address 可以得出这个对象是在 heap 堆上.

而 c 和 c1 本身是2个不同的指针, 他们里面都存的是 0x0000000100679af0 这个地址.

swift

复制代码

(lldb) po withUnSAFePointer(to: &c, {print($0)})

0x0000000100008298

0 elements

(lldb) po withUnSAFePointer(to: &c1, {print($0)})

0x00000001000082a0

0 elements

延伸阅读:

二、SIL是什么

Swift Intermediate Language,Swift高级中间语言,Swift 编译过程引入SIL有以下优点:

完全保留程序的语义既能进行代码的生成,又能进行代码分析处在编译管线的主通道 (hot path)架起桥梁连接源码与LLVM,减少源码与LLVM之间的抽象鸿沟

SIL会对Swift进行高级别的语意分析和优化。像LLVM IR一样,也具有诸如Module,Function和BasicBlock之类的结构。与LLVM IR不同,它具有更丰富的类型系统,有关循环和错误处理的信息仍然保留,并且虚函数表和类型信息以结构化形式保留。它旨在保留Swift的含义,以实现强大的错误检测,内存管理等高级优化。

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

sql server2012r2所在服务器做端口限制,需要开放什么端口才能继续访问数据库?

2023-10-17

Oracle有什么优势和劣势?

2023-10-17

CSS 隐藏页面元素有哪些方法?

2023-10-17

最新文章NEW

数据库聚集索引非聚集索引实现上有哪些区别?

2023-10-17

开发web应用,好的开发流程是怎么样的?

2023-10-17

为什么说Gradle是Android进阶绕不去的坎?

2023-10-17

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>