1. 一个简单的赋值语句
var num = 30
var num2 = num
打印内存地址
p withUnsafeMutablePointer(to: &num){print($0)}
0x000000016fc8f4a8
p withUnsafeMutablePointer(to: &num2){print($0)}
0x000000016fc8f4a0
x/4g 0x000000016fc8f4a8 // num
0x16fc8f4a8: 0x000000000000001e 0x0000000000000000
0x16fc8f4b8: 0x00000001ec28d000 0x00006000002708e0
x/4g 0x000000016fc8f4a0 // num2
0x16fc8f4a0: 0x000000000000001e 0x000000000000001e
0x16fc8f4b0: 0x0000000000000000 0x00000001ec28d000
p num = 8 // 修改num
x/4g 0x000000016fc8f4a0
0x16fc8f4a0: 0x000000000000001e 0x0000000000000008
0x16fc8f4b0: 0x0000000000000000 0x00000001ec28d000
可以看到 0x000000016fc8f4a0 和 0x000000016fc8f4a8 存储的值都是18,是分别存储的
2. 值类型 struct
struct AdModel {
var title: String = "a"
var num: Int = 10
}
var a = AdModel()
var b = a
(lldb) p a
(SnapKitDemo.AdModel) (title = "a", num = 10)
(lldb) p b
(SnapKitDemo.AdModel) (title = "a", num = 10)
// 打印 a 的地址
(lldb) p withUnsafeMutablePointer(to: &a) {print($0)}
0x000000016b52b488
// 打印 b 的地址
(lldb) p withUnsafeMutablePointer(to: &b) {print($0)}
0x000000016b52b470
// 读取 a 地址存储的
x/4g 0x000000016b52b488
0x16b52b488: 0x0000000000000061 0xe100000000000000
0x16b52b498: 0x000000000000000a 0x000000000000001e
// 读取 b 地址存储的
x/4g 0x000000016b52b470
0x16b52b470: 0x0000000000000061 0xe100000000000000
0x16b52b480: 0x000000000000000a 0x0000000000000061
0x000000000000000a == 10
0x0000000000000061 == "a"
// 修改a的num 并重新读a的内存地址
(lldb) p a.num = 16
x/4g 0x000000016b52b488
0x16b52b488: 0x0000000000000061 0xe100000000000000
0x16b52b498: 0x0000000000000010 0x000000000000001e
3. 引用类型 class
class AdModel2 {
var title: String = "a"
var num: Int = 10
}
var c = AdModel2()
var d = c;
// 打印 c 和 d 发现变量存储的内存地址是一致的
(lldb) p c
(SnapKitDemo.AdModel2) 0x0000600000c798f0 (title = "a", num = 10)
(lldb) p d
(SnapKitDemo.AdModel2) 0x0000600000c798f0 (title = "a", num = 10)
// 打印c的地址
(lldb) p withUnsafeMutablePointer(to: &c) {print($0)}
0x000000016b52b468
// 打印d的地址
(lldb) p withUnsafeMutablePointer(to: &d) {print($0)}
0x000000016b52b460
// 读取c地址存储的值
(lldb) x/4g 0x000000016b52b468
0x16b52b468: 0x0000600000c798f0 0x0000000000000061
0x16b52b478: 0xe100000000000000 0x000000000000000a
// 读取d地址存储的值
(lldb) x/4g 0x000000016b52b460
0x16b52b460: 0x0000600000c798f0 0x0000600000c798f0
0x16b52b470: 0x0000000000000061 0xe100000000000000
// 可以看到c地址存储的值和d地址存储的值是一样的,和上面通过`p c`, `p d`是一样的
// 读取 0x0000600000c798f0
x/8g 0x0000600000c798f0
0x600000c798f0: 0x00000001049f9998 0x0000000200000003
0x600000c79900: 0x0000000000000061 0xe100000000000000
0x600000c79910: 0x000000000000000a 0x0000000000000000
0x600000c79920: 0x0000beadde6a9920 0x00000000000007fb
0x600000c79900: 存储的是 title: String = "a"
0x600000c79910: 存储的是 num: Int = 10
// 修改c.num == 3, 发现 c 和 d值的num 都被改成了 0x0000000000000003
p c.num = 3
(lldb) p c
(SnapKitDemo.AdModel2) 0x0000600000c798f0 (title = "a", num = 3)
(lldb) p d
(SnapKitDemo.AdModel2) 0x0000600000c798f0 (title = "a", num = 3)
(lldb) x/8g 0x0000600000c798f0
0x600000c798f0: 0x00000001049f9998 0x0000000200000003
0x600000c79900: 0x0000000000000061 0xe100000000000000
0x600000c79910: 0x0000000000000003 0x0000000000000000
0x600000c79920: 0x0000beadde6a9920 0x00000000000007fb
4. Other
- 避免在struct中引用class
mutating
关键字修饰的func
会让func的默认参数self变成inout
类型的
struct Stack {
var items = [Int]()
mutating func push(obj: Int) {
items.append(obj)
}
}
// func 声明中默认参数是不可变,即用let 修饰的, 如果需要参数改变,可以加上 inout
// func push 没有添加mutating会报下面的错误
// Cannot use mutating member on immutable value: 'self' is immutable