一、汇编分析 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 ?
1.5 num 是如何相加的 51 ?
1.6 fn1 和 fn2
1.7 总结 1.01
1.8 什么时候捕获 1.16
1.9 num 是全局变量的是怎么样的?
2.0 本来就在堆空间的是怎么捕获的
2.1 练习里面两个闭包的情况产生捕获 1.32
共享一份堆空间
左右对等
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)