Swift学习笔记之闭包
简介 (真的很简)
闭包的完整形态是这个样子的:
{ (parameters) -> returnType in
statements
}
写在一行里就是这样:
{(parameters) -> (returnType) in statements}
形式
闭包以三种形式存在:
1.全局的函数都是闭包,它们有自己的名字,但是没有捕获任何值。
2.内嵌的函数都是闭包,它们有自己的名字,而且从包含他们的函数里捕获值。
3.闭包表达式都是闭包,它们没有自己的名字,通过轻量级的语法定义并且可以从上下文中捕获值。
捕获值
闭包可以捕获上下文的值,然后把它存储下来。至于存储的是引用还是拷贝,Swift 会决定捕获引用还是拷贝值,也会处理变量的内存管理操作。
下面这个例子可以说明很多问题:
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
let incrementByTen = makeIncrementor(forIncrement: 10)
incrementByTen() // runningTotal = 10
incrementByTen() // runningTotal = 20
incrementByTen() // runningTotal = 30
let incrementByTen2 = makeIncrementor(forIncrement: 10)
incrementByTen2() // runningTotal = 10
let incrementByTen3 = incrementByTen
incrementByTen() // runningTotal = 40
因为 incrementByTen2
声明了一个全新的闭包,所以 runningTotal
并没有继续接着上面的计数。而 incrementByTen3
和 incrementByTen
指向的是同一个闭包,所以 runningTotal
的值是累加的。
参数缩写
我们可以直接用 $0 $1 $2
这种来依次定义闭包的参数。比如 sorted
函数:
var reversed = sorted(["c","a","d","b"], { $0 > $1 }) // d c b a
尾随闭包
我一直觉得闭包最后这个 })
很难看,在 JS 中随处可见这种情况。如果闭包是函数的最后一个参数,Swift 提供了尾随闭包 (Trailing Closures) 解决这个审美问题:
// 以下是不使用尾随闭包进行函数调用
someFunc({
// 闭包主体部分
})
// 以下是使用尾随闭包进行函数调用
someFunc() {
// 闭包主体部分
}
OK那么前面那个排序的可以用尾随闭包这么改写:
var reversed = sorted(["c","a","d","b"]) { $0 > $1 } // d c b a
如果除了闭包没有其他参数了,甚至可以把小括号也去掉。
还记得我们前面写的 map
、 reduce
、 filter
三元大将吗?用尾随闭包可以让它们变得更好看。比如前面那个选出大于30的数字的 filter
就可以这样写:
var oldArray = [10,20,45,32]
var filteredArray = oldArray.filter{
return $0 > 30
}
println(filteredArray) // [45, 32]
变形
变形金刚神马的最有爱了。总结一下 closure
的变形大致有以下几种形态:
[1, 2, 3].map( { (i: Int) ->Int in return i * 2 } )
[1, 2, 3].map( { i in return i * 2 } )
[1, 2, 3].map( { i in i * 2 } )
[1, 2, 3].map( { $0 * 2 } )
[1, 2, 3].map() { $0 * 2 }
[1, 2, 3].map { $0 * 2 }
对比
通过 UIView 的 animateWithDuration
方法对 block 和 closure 进行简单的对比。
block 版本: [UIView animateWithDuration:1 animations:^{
可以看到原来的
// DO SOMETHING
} completion:^(BOOL finished) {
NSLog(@"OVER");
}]; closure 版本: UIView.animateWithDuration(1, animations: { () in
// DO SOMETHING
}, completion:{(Bool) in
println("OVER")
})^
符号已经不复存在,取而代之的是加在参数和返回值后面的in
。注意,如果有in
的话,就算没有参数没有返回值也一定需要()
,否则会报错。
总结
和 Objective-C 的 FuckingBlock 一样,Swift 出来之后 FuckingClosure 也就应运而生。总结了 Closure 的常用语法和格式:
// 作为变量
var closureName: (parameterTypes) -> (returnType)
// 作为可选类型的变量
var closureName: ((parameterTypes) -> (returnType))?
// 做为一个别名
typealias closureType = (parameterTypes) -> (returnType)
// 作为函数的参数
func({(parameterTypes) -> (returnType) in statements})
// 作为函数的参数
array.sort({ (item1: Int, item2: Int) -> Bool in return item1 < item2 })
// 作为函数的参数 - 隐含参数类型
array.sort({ (item1, item2) -> Bool in return item1 < item2 })
// 作为函数的参数 - 隐含返回类型
array.sort({ (item1, item2) in return item1 < item2 })
// 作为函数的参数 - 尾随闭包
array.sort { (item1, item2) in return item1 < item2 }
// 作为函数的参数 - 通过数字表示参数
array.sort { return $0 < $1 }
// 作为函数的参数 - 尾随闭包且隐含返回类型
array.sort { $0 < $1 }
// 作为函数的参数 - 引用已存在的函数
array.sort(<)
References
- Closures
- Closure Expressions in Swift
- Fucking Closure
- Writing completion blocks with closures in Swift
- Enough About Swift Closures to Choke a Horse
- Functions and Closures in Swift
- Swift How-To: Writing Trailing Closures
知识来源:http://lib.csdn.net/article/swift/474
Swift学习笔记之闭包的更多相关文章
- Swift学习笔记(9)--闭包
1.闭包表达式: { (parameters) -> returnType in statements } 注1.闭包表达式语法可以使用常量.变量和inout类型作为参数,不提供默认值. 也可以 ...
- swift学习笔记之-闭包
//闭包 import UIKit /*闭包(Closures): 函数.闭包.类都是引用类型(引用类型的实例赋值给变量或常量时,得到的都是该实例的引用,而值类型的实例变量得到的是独立的值的拷贝) 1 ...
- 【swift学习笔记】二.页面转跳数据回传
上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...
- Swift学习笔记(一)搭配环境以及代码运行成功
原文:Swift学习笔记(一)搭配环境以及代码运行成功 1.Swift是啥? 百度去!度娘告诉你它是苹果最新推出的编程语言,比c,c++,objc要高效简单.能够开发ios,mac相关的app哦!是苹 ...
- swift学习笔记2——函数、闭包
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- Swift学习笔记一
最近计划把Swift语言系统学习一下,然后将MagViewer用这种新语言重构一次,并且优化一下,这里记录一下Swift的学习笔记. Swift和Objective-C相比,在语法和书写形式上做了很多 ...
- 记录:swift学习笔记1-2
swift还在不断的更新做细微的调整,都说早起的鸟儿有虫吃,那么我们早点出发吧,趁着国内绝大多数的coder们还没有开始大范围普遍应用. 网上有些大神说:swift很简单!我不同意这个观点,假如你用h ...
- swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- swift学习笔记4——扩展、协议
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
随机推荐
- Vue2.5开发去哪儿网App 第三章笔记 下
1.样式的绑定 我们可以传给 v-bind:class 一个对象,以动态地切换 class 例如: :class="{activated:isactivated}" 上面的语法 ...
- socket实现两台FTP服务器指定目录下的文件转移(不依赖第三方jar包)
通过socket实现两台FTP服务器指定目录下的文件转移,其中包含了基础了ftp文件列表显示.上传和下载.这里仅供学习用,需掌握的点有socket.ftp命令.文件流读取转换等 完整代码如下: Ftp ...
- [Umbraco] 创建第一个页面
如何创建一个页面,很简单. 进入settings,首先右键点击“Document Types”, 在出现的菜单点击"Create",在弹出的窗口中 Master Document ...
- Service Fabric学习-从helloworld开始(无状态服务)
原先做服务器程序, 都是部署在xx云上, 也没理解云是个啥, 不就是个服务器(虚拟机)租赁商吗? 好吧, 其实这个是IaaS, 而接下来要学习的ServiceFabric(以下简称SF)是PaaS. ...
- (转)python3-staticmethod与classmethod
原文:https://blog.csdn.net/youngbit007/article/details/68957848 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blo ...
- 使用命令执行 sql 脚本文件
使用命令执行 sql 脚本文件 方法: 在 Windows 下使用 cmd 命令执行(或 Unix 或 Linux 控制台下)[Mysql的bin目录]\mysql –u用户名 –p密码 –D数据库名 ...
- [转]网页实时聊天之js和jQuery实现ajax长轮询 PHP
网页实时聊天之js和jQuery实现ajax长轮询 众所周知,HTTP协议是无状态的,所以一次的请求都是一个单独的事件,和前后都没有联系.所以我们在解决网页实时聊天时就遇到一个问题,如何保证与服务器的 ...
- SQL Server 2016 需要单独安装 SSMS
默认安装完 MSSQL 后,不自带 SSMS 的管理工具了,需要的话可以单独安装,貌似更专业了一些. https://msdn.microsoft.com/library/mt238290.aspx ...
- Error:Could not determine the class-path for interface com.android.builder.model.AndroidProject.
Android Studio导入Eclipse项目报错Error:Could not determine the class-path for interface com.android.builde ...
- Windows下的Jdk 1.7*安装并配置(图文详解)
不多说,直接上干货! 很多人很少去想,为什么在windows下,安装完Jdk的安装包之后,还需要去配置环境变量,只是知道要这么去做,没有想过为什么要去这么做? 答:由于java是平台无关的 ,安装jd ...