Swift类与结构体
结构体与类的主要相同点有
1、定义存储值的属性
2、定义方法
3、定义下标以使用下标语法提供对其值的访问
4、定义初始化器
5、使用extension来拓展功能
6、遵循协议来提供某种功能
主要的不同点有:
1、类有继承的特性,而结构体没有
2、类型转换能够在运行时检查和解释类实例的类型
3、类有析构函数用来释放其分配的资源
4、引用计数允许对一个类实例有多个引用
5、类是引用类型而结构体是值类型
6、最直观的区别:存储的位置不同,一般情况值类型存储在栈上引用类型存储在堆上
引用类型:意味着一个类类型的变量并不直接存储具体的实例对象,是对当前存储具体实例内存地址的引用
值类型:存储的是具体的实例(或者说是具体的值)
struct LTStruct{
var age : Int
var name : String
}
var s = LTStruct(age:20,name:"LT")
var s1=s
存储通过上图可知上面代码中,s存储LTStruct(age: 20, name: "LT") s1存储LTStruct(age: 20, name: "LT")
指令p和po的区别:po只会输出对应的值,而p则会返回值的类型以及命令结果的引用名
x/8g: 读取内存中的值(8g:8字节格式输出)
内存区域来一个基础概念的认知,可见下图:
内存区域图Stack:局部变量和函数运行过程中的上下文
Heap: 存储所有对象
Global:存储全局变量,常量,代码区
Segment & Section: Mach-O文件有多个段(Segment),每个段有不同的功能。然后每个段又分为很多小的Section
TEXT.text: 机器码
TEXT.cstring: 硬编码的字符串
TEXT.const:初始化过的常量
DATA.data:初始化过的可变的(静态/全局)数据
DATA.bss:没有初始化过的(静态/全局)数据
DATA.common:没有初始化过的符号声明
DATA.const:没有初始化过的常量
看下面例子:
struct LTStruct{
var age : Int = 20
var name : String = "LvTotti"
}
func test(){
var t = LTStruct()
print("end")
}
test()
frame variable输出struct其他条件不变,将struct修改成class的情况来看一下(代码就不贴啦,修改上面即可)
frame variable 输出classframe variable -L xxx 查看变量内存地址
通过上面的demo对比,可知Struct存储在栈区,class在堆区
由于Struct在栈区,而Class在堆区,而堆区在使用过程中始终有一个find的过程,所以栈区的效率要高些,因此:优先选择Struct
可以通过github上的案例StructVsClassPerformance来直观的测试结构体和类的时间分配
也可以查看苹果官方文档:Choosing Between Structures and Classes