swift-7-汇编分析闭包本质

一、汇编分析 fn1里面存放的东西

func testClosure2() {
    class Person {
        var age: Int = 10
    }
    
    typealias Fn = (Int) -> Int
  
    var num = 0
    func plus(_ i: Int) -> Int {
    num += i
    return num
    }
   return plus
    } // 返回的plus和num形成了闭包


 
    var fn1 = getFn()
    print(fn1(1)) // 1
    print(fn1(3)) // 4
    
    var fn2 = getFn()
    print(fn2(2)) // 2
    print(fn2(4)) // 6
}

1.1 常规函数的分析

 print(MemoryLayout.stride(ofValue: fn )) // 16  这个计算出来是16个字节

1.2 fn1 占用多少字节 不捕获变量的情况

但是 %rax 只能存8个字节,fun函数怎么返回16个的,进去看看

1.2 fn1 占用多少字节 捕获变量的情况 28

从下边可以看出alloc %rax 堆空间里面的地址都没有被修改 

 

1.3 fn1 是怎么调用的

通过分析 在 fn1 里面的16 个字节 前八个存的是函数地址,后八个存的是堆地址,那么在这里函数调用就不会是 callq + 写死的地址 而是从上面的地址取出前8个函数地址来调用,对应就是下边的这里就是fn1 的调用

* %rax 的取值过程

1.4 fn1 参数传递 过程 50 

rdi、rsi、rdx、rcx、r8、r9等寄存器常用于存放函数参数

1.5   num 是如何相加传进来的i的 51 是如何访问堆空间的mum 的

通过前面的分析,mum是存在对空间24个字节中的后8个字节中,那么我们就要看这里的后8个字节是怎么去到传进plus 函数的 

上面的证明

查看事如何相加的

查看%rcx 是什么

查看0x10(%rdx)是什么

0x10(%rdx) 这里面%rdx加16 就是mum的值了

加完后是怎么又放进堆空间的 100

1.6  fn1 和 fn2 

1.7 总结 1.01

1.8 什么时候捕获 1.16

是在return plus 的时候才捕获,所以在 num =11 和 num =14的时候,最终加出来的值以14为准

所以这里是15 因为最开始num 是14

汇编分析

所以要返回plus 的时候才捕获num的值,才分配对空间

所以最后捕获到num的值是14 ,因为在return 之前num 是14

1.9 num 是全局变量的是怎么样的?1.18

不会捕获,不会分配堆空间

为什么局部变量要分配堆空间,是要报住他的名

2.0 本来就在堆空间的是怎么捕获的

2.1 练习里面两个闭包的情况产生捕获 1.32

调用一次getFns 只会分配一份堆空看,里面的两个函数共享一份堆空间

左右对等

2.2 函数遍历的捕获

 

2.3 如果返回值是函数类型,那么参数的修饰要保持统一

func add(_ num: Int) -> (inout Int) -> Void {
func plus(v: inout Int) {
v += num
}
return plus
}
var num = 5
add(20)(&num) print(num)

2.4 自动闭包 2.04

2.4.1 有时候有可能返回,有可能不返回的情况

2.4.2 自动闭包 2.10

自动生成一个闭包,如写了@autoclosure 后, @autoclosure 会自动将 20 封装成闭包 20 }

2.4.3 空合并运算符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值