美文网首页
第七节 闭包二

第七节 闭包二

作者: 天明天 | 来源:发表于2021-02-02 14:18 被阅读0次

一.闭包的内存

1.闭包捕捉的num相当于 类的成员变量,闭包的方法,相当于类的实例方法。

typealias Fu = (Int) - > Int

func getFn() -> Fn {

//局部变量,这里会分配堆空间 便于下面的函数捕获他
 var num = 0

  func plus(_ v1 : Int) ->Int{
   num += v1
   return  num

 } 

 return plus

}  

var fn1 = getFn()
  • 查看fn1的内存地址、以及内容一般的常用方法在这里不支持
//打印普通变量地址,在这里含有函数,所以无法打印
print(Mens.ptr(ofVal: &fn1))
print(Mens.memStr(ofVal: &fn1))//打印普通对象内容

  • 借助汇编语言来做
MemoryLayout.stride(ofValue: fn1)//占用多少字节
 //16 字节

这里注意内存地址与内存地址的存储内容的区别(类似于房间编号跟房间里的人的区别)

截屏2020-07-28 下午2.36.00.png
  • movq :每次向后移动8个字节,把rax赋值给后面的地址值
  • call 函数调用,后面接函数地址

结论:

  • fun1 总共占用16个字节的内存
  • fun1 的前面 8 个字节放置的就是plus的函数地址
  • fun1 的后面的8个字节放置的是堆空间的地址值(房间里面放的是num的数值)
  • plus接受了两参数:i的值跟num的堆空间地址值
  • num的释放时机:arc下 没有强指针指向它时候 就会被释放。没有内存泄漏的风险。
  • num 的捕获时机:在调用return返回函数地址时捕获
  • 如果num是全局变量,plus函数是不会捕获num的值的,没有分配堆空间。
func getFn() -> Fn {

//局部变量,这里会分配堆空间 便于下面的函数捕获他
 var num = 0

  func plus(_ v1 : Int) ->Int{
   num += v1
   return  num
 } 

 num = 10
 return plus

}  

var fn1 = getFn()
print(fn1(1)) //打印结果是:11

注意:这里print(fn1(1)) //打印结果是:11。这里捕获的变量值是10,而不是0。捕获的时机是在return返回函数的时候

练习1.
截屏2020-07-28 下午3.28.28.png
这里:i << 1 相当于 i * 2

let (p,m) = getFuns()
print(p(6))   // (6,12)
print(m(5))  // (1,2)
print(p(3))  // (5,10)
print(m(2))  //(2,4)


  • getFun 返回 两个函数组成的元组,
  • 打印结果说明,这里 num1 跟num2 都是同一份,累计加减的结果。两个函数共享num1、mum2,捕获的变量相当于成员变量。
  • 类似下面的结构:
截屏2020-07-28 下午3.48.27.png
  • 元组这里面的元素能直接拿出来用,这里p = plus,m = minus。这里num1 跟 num2 都只是分配了 一次堆空间。
练习2.
var funs : [() -> int] = []

for i in 1...3{

   funs.append { i } // 尾随闭包的简写
  /*
   相当于:

   func myFunc () -> Int {
   
        return i
}
funs.append{ myFunc}
*/
}

for f in funs {

print(''\(f())'')//打印的是函数 // 打印数值:1、2、3

}
类比: 截屏2020-07-28 下午4.04.47.png

2. 注意:

截屏2020-07-28 下午4.08.38.png

3. 自动闭包

截屏2020-07-28 下午4.17.31.png
  • 这里 v2:变成函数 的目的是,当第一个条件满足时候,不在运行后面的函数。

如果这样写 getFirstPositive(_ v1:Int , _ v2: Int) -> Int{ return v1 > 0 ? v1 : v2}, 即使是v1 > 0, v2函数 仍然还是会调用。上面的写法是一种优化。

@autoclosure() 自动闭包:

截屏2020-07-28 下午4.24.45.png
  • 会自动将 参数20 生成闭包表达式。如果不写@autoclosure() 则写法为:getFirstPositive(10,{20})
  • @auticlosure () -> Int : 只支持 无参数的,并且有返回类型的闭包、
  • 其他说明:


    截屏2020-07-28 下午6.34.13.png
截屏2020-07-28 下午6.27.42.png
  • @autoclosure 可以构成函数的重载;

相关文章

  • 第七节 闭包二

    一.闭包的内存 1.闭包捕捉的num相当于 类的成员变量,闭包的方法,相当于类的实例方法。 查看fn1的内存地址、...

  • Web前端------JS高级闭包、沙箱介绍

    闭包介绍 闭包小案例(一) 闭包小案例(二) 闭包小案例(三)--------模拟点赞 效果展示: 沙箱 欢迎关注...

  • 函数表达式

    一、函数声明提升 二、递归 三、闭包(详见闭包)

  • 第三周第二天

    第三周第二天 函数作为参数,匿名函数(闭包)尾随闭包 闭包,尾随闭包 数组的过滤,缩减,映射

  • 二、闭包

    闭包是指有权访问另一个函数作用域的变量的函数。 上面匿名函数中的两行代码(注意点),访问了外部函数中的变量prop...

  • 函数对象和闭包

    函数对象和闭包 一) 函数对象 示例: 二)函数嵌套 三)闭包函数

  • iOS&Swift&OC 闭包和Block的相互转化

    一、Swift的闭包 -> OC的block 二、OC的block -> Swift的闭包

  • swift-闭包

    闭包 闭包定义 闭包简化 - 尾随闭包 闭包参数 闭包返回值 闭包的循环引用

  • JavaScript 闭包

    本篇文章包懂 什么是闭包 总有人看到闭包就头疼,因为“闭包”二字实在让人搞不懂它的语义。但闭包其实是个很简单的概念...

  • 理解javascript(匿名函数和闭包)这篇文章就够了

    匿名函数就是没有名字的函数,闭包是可访问一个函数作用域里变量的函数。 一.匿名函数 二:闭包 闭包的概念:闭包是指...

网友评论

      本文标题:第七节 闭包二

      本文链接:https://www.haomeiwen.com/subject/oxqtrktx.html