SwiftCafe 咖啡时光 - 了解 Swift 中的闭包
闭包(Closure) 是现代开发语言的必备特性,极大的提高了我们的开发效率。
关于闭包,你可以把它理解为一种特殊的变量或对象。简而言之,我们通常的对象,里面存储的是变量或对象的值,而闭包里面存储的是一段可执行的代码或函数,确切的说,是函数的地址。
我们都知道 UIButton 的 addTarget 方法。
button.addTarget(self, action: Selector("handler:"), forControlEvents: UIControlEvents.TouchUpInside)
给这个按钮添加一个点击事件,我们传入一个 selector 作为事件名称,而这个 selector 的具体定义却在别的地方。所以这个不是闭包。
我们在来看一个 GCD 的例子:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
// some code
})
我们看到 GCD 调用,将要执行的代码块直接放到了调用处,而不是像上面那个 Selector 那样将定义和声明分开来。
这种方式的好处已经显而易见了,比如讲代码块和调用处放在一起,让代码的可读性更直观等等,再比如,使用闭包可以实现引用当前上下文中的变量,而传统的函数调用方式是不能实现的。
总而言之,闭包无比强大,更多原理还可以参看这篇文章:http://swiftcafe.io/2015/02/14/swift-tips-func-closure
这里主要给大家介绍下 Swift 语言中闭包的使用方式。
首先我们看到前面 GCD 例子中的最后一个参数:
{ () -> Void in
// some code
}
这个就是闭包常量的表达方式,一对大括号是闭包的函数体,第一行中的 () -> Void 作为闭包函数的声明,小括号中是闭包的参数列表, -> 符号后面声明的是闭包的返回类型。
上面的那个闭包常量,我们还可以将它保存到变量中:
let callback: () ->Void = { () -> Void in
// some code
}
很明显吧,变量的名字叫做 callback,它的类型是一个闭包 () -> Void ,后面将相同类型的闭包常量赋值给它。
同样的,闭包还可以接受参数,比如这样:
let sum: (left:Int, right:Int) -> Int = { (left:int, right:Int) -> Int in
return left + right
}
闭包的调用也很简单,我们刚刚定义了一个 sum 闭包变量,我们就可以按照它的定义来调用它:
let result = sum(3,4)
闭包还可以作为类的属性:
class Calculator {
var calculate:(number:Int) -> Int = { (number: Int) -> Int in
return number * 2
}
}
我们调用它的时候,就可以这样:
let calculator = Calculator()
let result = calculator.calculate(3) //result = 6
细心的朋友就会想了,这不就是类方法么,我们完全可以这样定义:
class Calculator {
func calculate(number: Int) -> Int {
return number * 2
}
}
就可以用同样的方式来调用这个函数,那定义一个闭包成员变量又好在哪儿呢?
刚才我们只说了其一,还没说其二,闭包变量的一个特点就是,我们可以以相同的调用接口,达成不同的底层实现,因为闭包是变量,所以闭包变量也可以声明称 Optional 类型的,那么我们继续看这个例子:
class Calculator {
var calculate:((number:Int) -> Int)?
func handleNumber(number:Int) -> Int {
if let closure = self.calculate {
return closure(number)
}else {
return number
}
}
}
这次,我们的闭包成员变量 calculate 仅仅作为一个 Optional 成员变量,我们预先没有给他定义任何实现。我们又定义了一个 handleNumber 方法,这个方法中对 calculate 进行了判断,如果我们给 calculate 提供了实现,就会按照 calculate 闭包的实现来处理传递进来的参数,否则就会直接将参数返回。
来看一下具体的调用方式吧:
let calculatorForDouble = Calculator()
calculatorForDouble.calculate = { (number:Int) -> Int in
return number * 2
}
let result = calculatorForDouble.handleNumber(2) //result = 4
let calculatorForDivisonBy2 = Calculator()
calculatorForDivisonBy2calculate = { (number:Int) -> Int in
return number / 2
}
let resultDivision = calculatorForDouble.handleNumber(2) //result = 1
这次明确啦,我们看到,我们用同样的 Calculator 类的两个实例,的同一个方法,实现了两个完全不同的操作,这也是闭包的一个精妙之处。
理解闭包其实不难,我们只需要把变量的概念扩散开,变量除了存放数字,字符串等这些值内容,还可以存放像闭包这样的执行内容,这也是我们编程思路的一个体现。
大家还可以看看这篇文章,对闭包概念有更深入的了解:http://swiftcafe.io/2015/02/14/swift-tips-func-closure
SwiftCafe 咖啡时光 - 了解 Swift 中的闭包的更多相关文章
- Swift中的闭包(Closure) 浅析
转载自:http://www.devtalking.com/articles/closure-expressions-in-swift/ 闭包在Swift中非常有用.通俗的解释就是一个Int类型里存储 ...
- Swift 中的闭包与 C 和 Objective-C中的 blocks 以及其它一些编程语言中的 lambdas 比較类似。
闭包是功能性自包括模块,能够在代码中被传递和使用. Swift 中的闭包与 C 和 Objective-C中的 blocks 以及其它一些编程语言中的 lambdas 比較相似. 闭包能够 捕获 和 ...
- Swift中的闭包(Closure)[转]
闭包在Swift中非常有用.通俗的解释就是一个Int类型里存储着一个整数,一个String类型包含着一串字符,同样,闭包是一个包含着函数的类型.有了闭包,你就可以处理很多在一些古老的语言中不能处理的事 ...
- swift中的闭包总结
闭包是功能性自包含模块,可以在代码中被传递和使用. Swift 中的闭包与 Objective-C中的 blocks 以及其他一些编程语言中的 lambdas 比较相似. 闭包的基本语法 闭包表达式语 ...
- Swift中方法闭包参数不能省略括号的一种情况
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们知道在swift中,如果方法的最后一个参数是一个闭包类型, ...
- [Swift]UIAlertController 以及 Swift 中的闭包和枚举
原文地址:http://blog.callmewhy.com/2014/10/08/uialertcontroller-swift-closures-enum/ 在 iOS8 的 SDK 中, UIK ...
- Swift: 比较Swift中闭包传值、OC中的Block传值
一.介绍 开发者对匿名函数应该很清楚,其实它就是一个没有名字的函数或者方法,给人直观的感觉就是只能看到参数和返回值.在iOS开发中中,它又有自己的称呼,在OC中叫Block代码块,在Swift中叫闭包 ...
- iOS开发之OC与swift开发混编教程,代理的相互调用,block的实现。OC调用Swift中的代理, OC调用Swift中的Block 闭包
本文章将从两个方向分别介绍 OC 与 swift 混编 1. 第一个方向从 swift工程 中引入 oc类 1. 1 如何在swift的类中使用oc类 1.2 如何在swift中实现oc的代理 ...
- swift中闭包的学习。
在swift中的闭包等同于OC中的block,它的用途就是在于可以包装一段代码在必要的时候进行调用. 闭包定义: {(类型列表) -> 返回值 in // 多条swift语句 // 执行代码 ...
随机推荐
- ios开发网络学习五:输出流以及文件上传
一:输出流 #import "ViewController.h" @interface ViewController ()<NSURLConnectionDataDelega ...
- iOS开发Quzrtz2D:十一:图片截屏以及图片擦除
一:图片截屏:截取的是控制器的view #import "ViewController.h" @interface ViewController () @end @implemen ...
- MinGW 与MSVC的区别
Qt 中有两种方式编译,一种是MinGW ,另一种MSVC. 其中:MSVC是指微软的VC编译器 MingGW是指是Minimalist GNU on Windows的缩写.它是一个可自由使用和自由发 ...
- Android 升级到android studio 2.2项目死活run不起来
背景:升级到Android studio 2.2项目死活运行不起来 现象如下: run with --stacktrace --debug等等抛出的bug简直无法忍视 解决办法:把compileSdk ...
- php汉字字符串长度和截取
mb_strlen("你好123",'utf-8');//返回5 strlen("你好");//返回几我也不知道,肯定不是2,但你想要2就用上面的 substr ...
- Ubuntu,右键->在终端中打开(apt-install,或者手动增加右键菜单)
方法一: sudo apt-get install nautilus-open-terminal 然后重启 方法二: Ubuntu中,默认右键菜单中没有“在终端中打开”.要想添加此菜单,可以在主目录中 ...
- 数据序列化之protobuf
数据序列化之protobuf 很多时候需要将一些数据打包,就是把这些数据搞在一起,方便处理.最常见的情况就是把需要传输的数据,当然数据不止一条,打包成一个消息,然后发送出去,接收端再以一定的规则接收并 ...
- 使用Delegate在两个ViewController之间传值
以下就实现了使用Delegate在两个ViewController之间传值,这种场景一般应用在进入子界面输入信息,完后要把输入的信息回传给前一个界面的情况,比如修改用户个人信息,点击修改进入修改界面, ...
- KVM,QEMU核心分析
现在的问题是学习虚拟化软件KVM相关实施原则.处理,的源代码的分析总结,,若有不对的地方,希望大家提出. 因为有一些代码结构图或者是架构图上传比較麻烦.所以博文都放在了自己的个人博客上.麻烦大家移步查 ...
- 西方教育骗局,终于明白精英和普通人的残酷差别!(该校流传着一个数字——4。即“4小时睡眠、4杯咖啡、GPA4.0”——要想获得满分为4分的成绩,每天只睡4个小时,困了就喝4大杯咖啡)
2018-02-14 00:00英国/私立学校 你不知道的是:西方教育通过一个宽松的过程,偷偷完成了社会分层. 1 “中国学生真是太苦了!”我的同学李女士总是发出这样的感慨. 李女士是我中学同学,在一 ...