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. Java并发——ReentrantLock
  2. 洪嘉振 计算多体系统动力学pdf_如何在多体动力学模型中评估齿轮啮合刚度
  3. Android MVC模式在android系统中的体现
  4. HTML滚动条S默认最小值,css修改滚动条默认样式
  5. matlab图像增强分段线性函数_图像增强、锐化,利用 PythonOpenCV 来实现 4 种方法!...
  6. C++基础13-类和对象之继承1
  7. 10.28T5 tarjan+dfs
  8. 渗透学习笔记--基础篇--sql注入(数字型)
  9. “Master”连胜世界围棋冠军,谁是幕后智能引擎?
  10. Java Annotaion认识
  11. MQTT 测试工具介绍
  12. SecureCRT安装破解教程
  13. 麻将 java_怎么用java做麻将游戏
  14. 主观意义上第一个基于DEFI的DAM平台DIPPER,年关崛起的黑马究竟是否能在新年创造区块链新纪元?而DIPPER的意义和价值又是什么?
  15. (自兴人工智能)python猜数字游戏
  16. 货拉拉2021岗位招聘内推计划开始啦
  17. 主题:内存的管理 DATE:2004-09-17
  18. 斥候密报_魔兽世界:解锁德拉诺飞行成就指南,并有宝箱插件分享
  19. android如何设置qq邮箱格式,如何利用安卓“电子邮件”客户端添加QQ邮箱
  20. Android自动化埋点的实践

热门文章

  1. lazarus ui设计_Golang绑定VCL和LCL组件
  2. navicat mysql 存储过程_navicat怎么创建存储过程
  3. 7段数码管显示驱动电路参数推导
  4. AlarmManager 中 setRepeating用法
  5. 玩转json——json-->txt
  6. 最新New Bing使用详细教程(微软Coplilot)
  7. java.lang.IllegalArgumentException: baseUrl must end in /: http://xxx.xxx.x.xxx:xxxx/Handler1.ashx
  8. 项目团队的信任问题探讨
  9. java 第三方登录之新浪微博登录
  10. 用计算机数字弹侧脸,侧脸钢琴简谱-数字双手-于果