一.闭包创建语法
{(parameters) -> return type in
statements
}
例子 :
let names = ["Chris","Alex","Ewa","Barry","Daniella"]
func backward( s1: String,_ s2: String) ->Bool {
return s1 > s2
}
var reversedNames = names.sort(backward)
上面的是传入普通函数,我们也可以传入一个闭包
reversedNames = names.sort({ (s1:String, s2: String) -> Boolin
return s1 > s2
})
二.闭包类型推断
闭包被当做参数传入方法时,闭包的参数类型和返回值有可能被推断出来,这时我们可以省略参数类型和返回值, 因此上面的 例子也可以写成:
reversedNames =names.sort({ s1, s2 inreturn s1 > s2 } )
reversedNames = names.sort({ s1, s2 in s1 > s2 } )
二.简短的参数名
如果我们知道函数的类型,既我们可以从函数里知道,传入函数的闭包需要几个参数每个参数的类型是什么,我们 可以省略闭 包的参数列表,in 关键词也可省略,因为此时闭包里全为可执行语句。通过$0,$1,$2......的方式来引用传 入的参数
reversedNames =names.sorted(by: { $0 > $1 } )
三. Trailing Closures
reversedNames = names.sort { $0 > $1 }
四.捕获值
闭包可以捕获在闭包外面内容常量和变量,闭包可以引用和改变这些常量和变量。闭包的捕获使这些变量和常量不 被释放。
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrementer(forIncrement: 10)
incrementByTen()
// returns a value of 10
incrementByTen()
// returns a value of 20
incrementByTen()
五.闭包是引用类型
当您将一个函数或一个闭包赋给一个常量或一个变量时,您实际上是在设置常量或变量来引用函数或闭包的函数。
六.闭包的Non-Escaping和 Escaping
Non-Escaping Closures
注意闭包没有从这函数体内逃逸。当函数结束,传入的闭包从函数体出来时,没有添加额外的引用。闭包的引用计数在函数开始执行和结束是相同的
Escaping Closures
Escaping and Non-Escaping in Swift 3
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)
// Prints "200"
completionHandlers.first?()
print(instance.x)
// Prints "100"
在逃逸闭包里必须用 self 来引用外围的内容,而非逃逸闭包则不用。
七.自动闭包
一个自动闭包是一个没有参数,包裹一个表达式的闭包。当我们调用这个闭包它返回这个表达式的值。
print(customersInLine.count)
// Prints "5"
let customerProvider = { "ddd";}
print(customersInLine.count)
// Prints "5"
print("Now serving \(customerProvider())!")
// Prints "Now serving Chris!"
print(customersInLine.count)
// Prints "4"