Closure 的定义网上也比较多比较全,下面所写不会具体介绍语法,只做简单归纳、实例阐述。
一、归纳属性闭包
1.常见的完整的属性闭包写法
//定义
var fun1 = {
(a:Int,b:Int) -> Int in
return a+b
}
//调用
print(fun1(1,1))
2.定义后立即调用
var fun2 = {
(a:Int,b:Int) -> Int in
return a+b
}(1,2)
3.闭包的类型实际上是一种函数类型,根据接收变量的类型来自动推到闭包对应的类型
var fun3:(Int,Int)->Int = {
(a,b) in
return a+b
}
print(fun3(1,3))
4.闭包的类型实际上是一种函数类型,根据实参的类型和返回值来自动推到闭包对应的类型
var fun4 = {
a,b in
return a+b
}(1,4)
5.省略return语句
var fun4 = {
a,b in
a+b
}(1,4)
6.省略形参名和in关键字(可以是用$0,$1...来应用对应参数)
var fun5:(Int,Int)->Int = {
$0 + $1
}
print(fun5(1,5))
var fun6 = {
$0 + $1
}(1,5)
二、Closure 在函数中的应用
1.尾随闭包
定义:闭包表达式可以作为函数的参数传递,如果闭包表达式很长,就会影响程序的可读性。尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。
func showPlus(opr:String,fun:(Int,Int)->Int){
switch (opr) {
case "+" :
print("1 + 1 = \(fun(1,1))")
default:
print("1 - 1 = \(fun(1,1))")
}
}
//正常调用
showPlus(opr: "+", fun: {(a:Int,b:Int)->Int in return a+b})
//尾随闭包
showPlus(opr: "-"){(a:Int,b:Int)->Int in return a-b}
2.捕获值
闭包可以访问本体之外的变量或常量,函数和闭包都是引用类型
func makeIncrementer(forIncrement amount: Int)->(Void)-> Int{
var runningTotal = 0
func incrementer()->Int{
runningTotal += amount
return runningTotal
}
return incrementer
}
let funMI = makeIncrementer(forIncrement: 10)
funMI()
funMI()
funMI()
3.非逃逸闭包
定义:闭包closureHandler作为一个参数传递给一个函数的时候,funcClosure函数返回了才执行闭包,我们就说闭包逃逸了。当我们用@noescope修饰闭包时,该闭包的生命周期不能超出该函数,同时不能被中的其他闭包捕获。假如给closureHandler加上@noescope修饰就会报错
var closureArray: [() -> Void] = []
func funcClosure(closureHandler: () -> Void) {
closureArray.append(closureHandler)
}
5.自动闭包
将表达式包装成闭包,为了不会浪费资源选择性求值,调用方式不变,参数写法不同
func verifyidentity(action1:Bool, action2:Bool){
}
func isAction1()->Bool{
print("isAction1 is action")
return true
}
func isAction2()->Bool{
print("isAction2 is action")
return true
}
verifyidentity(action1: isAction1(), action2:isAction2())
三、回调实例
class A{
//可以用关键字typealias定义一个公共的Closure,不需要理解,就下面这种定义就行了
typealias Block = (wu:NSString,dan:NSString)->()
var block:Block
init() {
self.block = {
name,dan in
print(name)
}
print("函数已经结束")
}
}
class B{
var a:A?
func action(){
self.a?.block(wu: "wudanfeng",dan: "10")
}
}
var a = A()
var b = B()
b.a = a
b.action()