Swift Day07 闭包探索

一、闭包

1. 请问下面代码的输出?
问题
  • 输出 11 14
  • num 是在 getFn 调用,并且 return plus 之前捕获的
2. 下面代码会对 person1 进行捕获吗?
题目
  • 从汇编来看不会捕获,fn1 后 8 个字节存放了 person1 的地址值
3. 下面函数打印什么?
image.png
  • 打印 1 2 3
  • 应该是三次驳货

二、探索普通函数变量的内存放着什么?

1. 首先我们探索一下,一个正常的普通函数变量,它所占据的字节大小?
func sum(_ v1: Int, _ v2: Int) -> Int { v1 + v2 }
var fn = sum
print(MemoryLayout.stride(ofValue: fn))
// 输出: 16
  • 输出 16,表示普通函数,Swift 给他分配了 16 个字节
  • 按照我们的理解,正常情况下一个函数的地址仅需要 8 个字节,那么 16 个字节到底放着什么呢?
2. 我们在上题函数的 print行 打上断点,进入汇编模式
汇编图
  • %rcx 是 sum 函数的地址,赋值给了 fn 的前 8 个字节
  • 0x0 赋值给了 fn 的后 8 个字节
  • 另外我们可以计算 sum 的地址,然后打印 sum 的地址,两者一致,表示我们的猜想正确
侧面证明

三、探索闭包变量的内存放着什么?

1. 闭包变量代码如下
闭包变量
  • 进入汇编模式,查看 fn116 字节放着什么?
汇编
  • 从汇编代码结合 xcode 提示,我们知道%rax 赋值给了 fn1 的前 8 个字节
  • %rdx 赋值给了 fn1 的后 8 个字节
2. 接下来我们要弄懂 %rax 和 %rdx 分别存放什么?
  • %rax 和 %rdx 通常放着函数的返回值,所以我们要弄懂 callq 函数里面给这两个寄存器放了啥?

  • 所以我们需要在 return plus 行打上断点


    汇编以及分析
  • register read rax 查看获得 rax = 0x0000000100000e80

  • register read rdx 查看获得 rdx= 0x0000000100575170

3. 接下来我们要继续跟进,确认 %rdx 到底存放什么?
  • 我们进入 callq 0x100000ea6
4. 接下来我们要继续跟进,确认 %rax 到底存放什么?是否真的是 plus 地址?
5. 太难了,这篇文章猝死了。

你可能感兴趣的:(Swift Day07 闭包探索)