闭包(Closures)是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。类似于OC
中的block
,js
中的匿名函数以及其他一些编程语言中的匿名函数。
1、全局函数:有名字但不能捕获任何值;
2、嵌套函数:有名字,也能捕获封闭函数内的值;
3、闭包表达式:无名闭包,可以根据上下文环境捕获值。
一、语法定义
{(paraments)->return type in
statements
}
示例:
let closure1 = {(arge:Int)->Int in
return arge+10
}
print(closure1(5))
let closure2 = {print("无参数,无返回值闭包")}
closure2()
二、sorted方法
将已知类型数组中的值进行排序。排序完成后,返回一个与原数组大小相同,包含同类型元素且元素已正确排序后的新数组。
var names = ["a","z","e","b"]
//普通排序
func backwards(s1:String, s2:String)-> Bool{
return s1>s2
}
var reversed = names.sorted(by: backwards)
print(reversed)
//简略参数名-提供简略参数名给单行闭包,这些简略参数名是被用来引用闭包的参数的,如$0、$1、$2等
names = ["a","z","e","b"]
reversed = names.sorted(by: {$0>$1})
reversed = names.sorted(){$0>$1}//尾随闭包和以上等价
print(reversed);
//运算符方法
names = ["if","ts","da","ge"]
reversed = names.sorted(by: >)
print(reversed)
二、尾随闭包
尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。
//尾随闭包
func someFunctionThatTakesAClosure(closure:()->Void){
print("hhhhhh")
}
//非尾随闭包进行函数调用
someFunctionThatTakesAClosure(closure: {
print("aaaa")
})
//尾随闭包进行函数调用
someFunctionThatTakesAClosure(){
}
三、捕获值
闭包可以从包含这个闭包的方法中获取这个方法的内部定义的常量或变量。
//捕获值
func makeIncrementer(forIncrement amount:Int)->()->Int{
var runningTotal = 0
func incrementer()->Int{
runningTotal += amount
return runningTotal;
}
return incrementer;
}
var increment = makeIncrementer(forIncrement: 10)
print(increment())//10
print(increment())//20
通过获取闭包你变量指针来引用变量的,在执行完后不会消失,在下次调用还会继续使用。从新创建对象,变量会被重新初始化。
四、逃逸闭包
当闭包作为参数传入到一个方法,在方法内部返回之后才能调用。在方法类型之前使用@escaping
在说明闭包允许逃逸。类比于OC
中的block
网络请求到数据后通过block
返回请求到的数据block(data)
。
//逃逸闭包
var completionHandlers:[()->Void]=[]
func someFunctionWithEscapingClosure(completionHandler:@escaping()->Void){
completionHandlers.append(completionHandler)
}
func someFunctionWithNonescapingClosure(closure:()->Void){
closure()
}
class SomeClass{
var x = 10
func doSomething() {
someFunctionWithEscapingClosure{self.x=100}
someFunctionWithNonescapingClosure {x=200}
}
}
let instance = SomeClass()
instance.doSomething()
print(instance.x)//200
completionHandlers.first?()
print(instance.x)//100