SwiftCafe 咖啡时光 - 了解 Swift 中的闭包
2015-10-23 23:47
477 查看
闭包(Closure) 是现代开发语言的必备特性,极大的提高了我们的开发效率。
关于闭包,你可以把它理解为一种特殊的变量或对象。简而言之,我们通常的对象,里面存储的是变量或对象的值,而闭包里面存储的是一段可执行的代码或函数,确切的说,是函数的地址。
我们都知道
给这个按钮添加一个点击事件,我们传入一个
我们在来看一个 GCD 的例子:
我们看到 GCD 调用,将要执行的代码块直接放到了调用处,而不是像上面那个 Selector 那样将定义和声明分开来。
这种方式的好处已经显而易见了,比如讲代码块和调用处放在一起,让代码的可读性更直观等等,再比如,使用闭包可以实现引用当前上下文中的变量,而传统的函数调用方式是不能实现的。
总而言之,闭包无比强大,更多原理还可以参看这篇文章:http://swiftcafe.io/2015/02/14/swift-tips-func-closure
这里主要给大家介绍下
首先我们看到前面 GCD 例子中的最后一个参数:
这个就是闭包常量的表达方式,一对大括号是闭包的函数体,第一行中的
上面的那个闭包常量,我们还可以将它保存到变量中:
很明显吧,变量的名字叫做 callback,它的类型是一个闭包
同样的,闭包还可以接受参数,比如这样:
闭包的调用也很简单,我们刚刚定义了一个
闭包还可以作为类的属性:
我们调用它的时候,就可以这样:
细心的朋友就会想了,这不就是类方法么,我们完全可以这样定义:
就可以用同样的方式来调用这个函数,那定义一个闭包成员变量又好在哪儿呢?
刚才我们只说了其一,还没说其二,闭包变量的一个特点就是,我们可以以相同的调用接口,达成不同的底层实现,因为闭包是变量,所以闭包变量也可以声明称
这次,我们的闭包成员变量
来看一下具体的调用方式吧:
这次明确啦,我们看到,我们用同样的
理解闭包其实不难,我们只需要把变量的概念扩散开,变量除了存放数字,字符串等这些值内容,还可以存放像闭包这样的执行内容,这也是我们编程思路的一个体现。
大家还可以看看这篇文章,对闭包概念有更深入的了解:http://swiftcafe.io/2015/02/14/swift-tips-func-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
相关文章推荐
- iOS巅峰之Swift结构体和类, 枚举, 构造器, 继承, 协议, 扩展(完结篇)
- iOS巅峰之Swift 函数, 闭包详解(下)
- ios深度解析之Swift(枚举,继承,协议,扩展)
- ios深度解析之Swift(结构体和类,属性)
- ios深度解析之Swift(函数)
- swift:创建表格UITableView
- iOS经典讲解之Swift匿名函数(闭包)(二)
- Swift基础知识
- Swift高级开发语言--结构体,类,构造器,属性
- Swift 基础语法 <与 OC作对比>
- Swift高级开发语言--枚举,继承,协议,扩展
- iOS经典讲解之Swift函数详解(一)
- 4.Swift初探-2048小游戏中的问题
- IOS开发:swift 语言基本语法1
- swift:入门知识之泛型
- Swift 语言概览
- swift:入门知识之协议与扩展
- swift:入门知识之枚举和结构体
- swift 多线程实现
- 《从零开始学Swift》学习笔记(Day 26)——可选链