var array=[ "I" , "have" , "a" , "apple" ] print(array.count) //打印出"4" letremoveBlock={array.remove(at:3)} //测试了下,这里代码超过一行,返回值失效。 print(array.count) //打印出"4" print( "执行代码块移除(removeBlock())" ) //打印出"执行代码块移除apple"这里自动闭包返回了apple值 print(array.count) //打印出"3" 5. 非逃逸闭包(Nonescaping Closures) 一个闭包作为参数传到一个函数中,但是这个闭包在函数返回之后才被执行,我们称该闭包从函数中逃逸。可以在参数名之前标注@noescape ,用来指明这个闭包是不允许“逃逸”出这个函数的。将闭包标注@noescape 能使编译器知道这个闭包的生命周期. 像刚才的数组的sort(_:) 函数中的参数就定义成了非逃逸闭包, public func sort(@noescape isOrderedBefore: (Self.Generator.Element,Self.Generator.Element) -> Bool) -> [Self.Generator.Element] 你可能会问什么时候会出现逃逸闭包呢?举个例子:很多启动异步操作的函数接受一个闭包参数作为 completion handler 。这类函数会在异步操作开始之后立刻返回,但是闭包直到异步操作结束后才会被调用。在这种情况下,闭包需要“逃逸”出函数,因为闭包需要在函数返回之后被调用。 非逃逸闭包和逃逸闭包讲的不是执行先后顺序吧,非逃逸是指你的闭包不能在函数外单独调用,只能在函数内部调用,函数调用完成后,那个闭包也就结束了。 下面举个逃逸闭包的例子: //声明一个存放函数的数组
var functionArray: [() -> Void] = []
//定义一个接收闭包参数的函数,如果定义非逃逸函数 func doSomething(@noescape paramClosure:() -> Void) 就会编译错误
func doSomething(paramClosure:@escaping () -> Void){
//把参数放入数组中,用于逃逸调用
functionArray.append(paramClosure)
}
//调用函数
doSomething(paramClosure: {print("Hello world")})
doSomething(paramClosure: {print("Hello LvesLi")})
//逃逸调用闭包
for closurePrama in functionArray {
print("(closurePrama)")
} |