一.结构体和类
结构体张这个样子
struct LsPoint{
var x : Int = 10
var y : Int = 11
}
类张这个样子
class LsPoint{
var x : Int = 10
var y : Int = 11
}
二.结构体和类的区别
- 针对结构体, 即使你没有定义函数,编译器也会自动生成初始化属性的函数;改成类后就没有了
图片.png
图片.png
- 结构体属性可以不用初始化,而类的属性如果不初始化会报错
图片.png
图片.png
- 结构体属于值引用,存储在栈区(sil内部调用alloc_stack),不会调用malloc方法;类属于引用类型,存储在堆区(sil内部调用__allocating_init),会调用malloc方法。
struct LsPoint{
var x : Int = 10
var y : Int = 11
}
var l1 = LsPoint()
var ptr1 = withUnsafeMutablePointer(to: &l1) {$0} //0x0000000100008040
print(ptr1)
var l2 = l1
var ptr2 = withUnsafeMutablePointer(to: &l2) {$0} //0x0000000100008060
print(ptr2)
print("end")
/*
(lldb) x/2wg 0x0000000100008040
0x100008040: 0x000000000000000a 0x000000000000000b
(lldb) x/2wg 0x0000000100008060
0x100008060: 0x000000000000000a 0x000000000000000b
将l1赋值给l2, 内存复制了一份,相当于深拷贝
*/
import Foundation
class LsPoint{
var x : Int = 10
var y : Int = 11
}
print(class_getInstanceSize(LsPoint.self)) //32字节
var l1 = LsPoint()
var ptr1 = withUnsafeMutablePointer(to: &l1) {$0} //0x0000000100d1ac20
//或者lldb 使用 po l1,lldb能直接打印堆区的对象,只是不能打印栈区的而已
print(ptr1)
var l2 = l1
var ptr2 = withUnsafeMutablePointer(to: &l2) {$0} //0x0000000100d1ac20
print(ptr2)
print("end")
/*
(lldb) x/4wg 0x0000000100d1ac20
0x100d1ac20: 0x0000000100008170 0x0000000200000003
0x100d1ac30: 0x000000000000000a 0x000000000000000b
我们发现l1和l2指针地址不一样,但是存储的地址值都是0x0000000100d1ac20, 打印0x0000000100d1ac20发现其中存储的10和11
*/
- 结构体和类的方法存储地方不一样
结构体的函数地址直接存放在全局区,在编译完成后就确定了地址,属于静态调用并不存储在结构体内部
从0x10003e80(大地址)也可以看出是存放在全局区
图片.png
图片.png
如果是class,就是动态寻址了
图片.png
FinalQuestion
- 为啥针对结构体编译器也会自动生成初始化属性的函数?
为啥啊 - 什么时候用结构体,什么时候用类啊
1.类可以实现继承,如果想做继承操作,可以使用类
2.结构体属于值类型,如果想要copy一个完整的对象,可以使用结构体。如果用类,还得实现copy协议,很麻烦
网友评论