1、闭包

Swift对闭包进行了简化:

  • 利用上下文推断参数和返回值类型
  • 隐式返回单表达式闭包,即单表达式闭包可以省略return关键字
  • 参数名称缩写
  • 尾随(Trailing)闭包语法

先来看一个排序的例子,数组的降序排列

let usernames = ["Wangwu", "Lisi", "Xiaoming", "Zhangsan"]
func backWards(s1: String, s2: String) -> Bool
{return s1 > s2
}
let resultName1 = usernames.sorted(by: backWards)
//resultName1: ["Zhangsan", "Xiaoming", "Wangwu", "Lisi"]

1.1 闭包表达式语法

{ (parameters) -> returnType instatements
}

1.2 单表达式闭包隐式返回

单行表达式闭包可以通过省略return关键字来隐式返回单行表达式的结果

let resultName2 = usernames.sorted { s1, s2 in s1 > s2 }

1.3 参数名称缩写

let resultName3 = usernames.sorted { $0 > $1 }

1.4 函数式闭包

let resultName4 = usernames.sorted(by: >)

2. 捕获值(Capturing Values)

闭包可以在其被定义的上下文中捕获常量或变量。即使定义这些常量和变量的原作用域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。

3.闭包是引用类型(Closures Are Reference Types)

和类一样,必要也是引用类型

4. 尾随闭包(Trailing Closures))

尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用:

        let numReult2 = caculateTwoNumbers(num1: 3, num2: 4) {  $0 * $1 }print(numReult2)func caculateTwoNumbers(num1: Int, num2: Int, CaluFunction: (Int, Int) -> Int) -> Int{return CaluFunction(num1, num2)}

5. 逃逸闭包(@escaping)

    func mainFunc(){//调用函数doSomething(paramClosure: {print("hello")})doSomething(paramClosure:{print("word!")})//逃逸调用闭包for closurePrama in functionArray {closurePrama()}//非逃逸闭包someFunctionWithNonescapingClosure { (a) inprint(a)}}//声明一个存放函数的数组var functionArray: [() -> Void] = []//定义一个接收闭包参数的函数,如果定义非逃逸函数 func doSomething(@noescape paramClosure:() -> Void) 就会编译错误func doSomething(paramClosure:@escaping  () -> Void){//把参数放入数组中,用于逃逸调用functionArray.append(paramClosure)}//非逃逸闭包 默认@noescape 可以省略不写func someFunctionWithNonescapingClosure(closure: (_ num:Int) -> Void) {let a = 1closure(a)}

6、noescape是非逃逸的意思。

@noescape关键字代码中扮演了一个标注的作用:来说明一个闭包参数,该闭包参数与此API是同步的,它只在此API中被调用。只要该API运行结束,该闭包的生命周期就结束。也就是说,该闭包逃不出该API的手掌心。哈哈哈哈!它对编译器和API调用者来说:编译器会对代码做一些优化,而API调用者则可以放心大胆的使用该API,不用因为担心造成引用循环而去使用捕获列表。同时在其中调用实例变量或实例方法的时候可以不使用"self."

但是!如何使用这个@noescape标注,这是需要正确的姿势的!

上面的论述,只有在闭包是临时创建,即没有被API外部的任何其他属性或全局变量持有的前提下才成立!!

func withLock(@noescape perform closure: () -> Void) {myLock.lock()closure()myLock.unlock()
}

In  Objective-C

- (void)performWithLock:(__attribute__((noescape)) void (^)())block {  // exposed as @noescape to Swift[myLock lock];block();[myLock unlock];
}

面试题:调用Masonry的block为何不用weak?

原因就是使用了栈block,都是用NS_NOESCAPE修饰block.编译器会相应地做一些优化,例如去掉一些多余的对self的捕获、retain、release操作。

- (NSArray *)mas_makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
- (NSArray *)mas_updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
- (NSArray *)mas_remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;

Swift 闭包(block)详解相关推荐

  1. 好程序员技术分析JavaScript闭包特性详解

    为什么80%的码农都做不了架构师?>>>    好程序员技术分析JavaScript闭包特性详解,今天来总结一下js闭包的那些事,以及遇到的坑和解决方法,希望对你有所帮助. 是的,没 ...

  2. Swift - 多线程GCD详解

    //  GCD详解 //  目录: //  1. 创建GCD队列(最常用) //  2. 自定义创建队列 //  3. 使用多线程实现延迟加载 //  4. 使用多线程实现重复(循环) //  5. ...

  3. oc开发之block详解

    2019独角兽企业重金招聘Python工程师标准>>> BLOCK是什么?苹果推荐的类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行.标识 ...

  4. javascript中的闭包closure详解

    文章目录 简介 函数中的函数 Closure闭包 使用闭包实现private方法 闭包的Scope Chain 闭包常见的问题 闭包性能的问题 总结 简介 闭包closure是javascript中一 ...

  5. colsure php_PHP Closure(闭包)类详解

    闭包就是能够读取其他函数内部变量的函数.例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成"定义在一个函数内部的函数".在本质上,闭包是将函数内 ...

  6. inode与block详解

    创建一个文件后,会同时创建一个inode和一个block,inode存放的是文件的属性信息,但是不包括文件名,并存放所对应数据所在的block块的地址的指针:block存放文件的数据,每个block最 ...

  7. linux存储--inode与block详解(八)

    Linux下的格式化命令是mkfs,mkfs在格式化的时候需要制定分区以及文件系统类型.该命令其实就是把我们的连续的磁盘空间进行划分和管理.我在我的机器上执行了一下,输出如下: # mkfs -t e ...

  8. linux存储--inode与block详解(七)

    基本概念 首先讲下inode和块的基本概念.在Linux系统中,文件由元数据和数据块组成.数据块就是多个连续性的扇区(sector),扇区是文件存储的最小单位(每个512字节).块(block)的大小 ...

  9. python值函数名的使用以及闭包,迭代器详解

    一.函数名的运用 函数名就是一个变量名,但它是一个特殊的变量名,是一个后面加括号可以执行函数的变量名. def func():print("我是一个小小的函数") a = func ...

  10. ios swift版 sqlite3详解

    iOS中的SQLite3的封装与详细应用 SQLite是一个开源的嵌入式关系数据库,特点是易使用.高效.安全可靠.可移植性强. iOS中的本地持久化存储 NSUserDefault:一般用于存储小规模 ...

最新文章

  1. 洛谷P1092 虫食算
  2. 深度学习中的双下降现象
  3. CC2538相关资料
  4. linux 文件重命名_Linux编程 5 (目录重命名与移动 删除,目录创建删除,查看file)...
  5. Delphi开发环境中应用层网络协议的实现
  6. 获取某个日期是一年中的第几周
  7. DevExpress v17.2新版亮点—Analytics Dashboard篇(一)
  8. 车轮轴承行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  9. Vant报错:[Vue warn]: Invalid prop: type check failed for prop “lazyLoad“. Expected Boolean, got String
  10. 湖仓一体数据平台架构
  11. Android基础--ListView的刷新
  12. 机器学习与数据挖掘复习笔记
  13. 消极风险应对策略的区别
  14. PowerBI可视化实战:商品销售动态ABC分析案例
  15. docker run 的 -i -t -d参数
  16. python模拟登录淘宝直通车_淘宝直通车推广计划
  17. Dubbo学习之DubboService
  18. 大数据投资人必读:中国大数据发展与投资分析报告
  19. QQ自定义个人文件夹
  20. 3月18日面试题复盘

热门文章

  1. Linux查看本机局域网IP命令
  2. 百度崔珊珊讲给年轻人的九个故事:和百度一起成长,然后改变世界
  3. 基于springboot在线考试报名系统 毕业设计-附源码031706
  4. 深耕智能制造,质子矩阵助力升级赋能
  5. EaselJS简明教程2-动画
  6. 记录下server的配置
  7. 外媒:京东方正寻求为苹果iPhone供应OLED屏幕
  8. C++opencv窗口不销毁引发引发异常0x00007FFBE76FA9C0 (ntdll.dll)处
  9. 虚电路和数据报的区别以及应用
  10. html图片加文字批量处理,图片批量加水印工具,图片批量添加文字|图片同时添加文字或图片水印...