5.5 后置闭包、逃逸闭包与自动闭包

闭包常常会作为函数的参数来使用,函数在调动时,参数是写在小括号中的参数列表中的,而闭包又是一个写在大括号中的代码块,如此的嵌套写法在视觉上十分不直观。因此,Swift语言中提供了后置闭包的写法。当函数中的最后一个参数为闭包参数时,在调用函数时,开发者可以将闭包结构脱离出函数的参数列表,追加在函数的尾部,增强代码的可读性,示例如下:

后置闭包的语法简化了代码的结构,这里面还有一个小技巧,如果一个函数只有一个参数,且这个参数是一个闭包类型的参数,则开发者在调用函数时,使用后置闭包的写法可以直接将函数的参数列表省略,示例代码如下:

以上示例代码几乎是闭包的最简形式了。

当闭包传递进函数时,系统会为此闭包进行内存的分配。在Swift语言中,还有逃逸闭包与非逃逸闭包这样的概念。所谓逃逸闭包,是指函数内的闭包在函数执行结束后在函数外依然可以进行使用,非逃逸闭包是指当函数的生命周期结束后,闭包也将被销毁。换句话说,非逃逸闭包只能在函数内部使用,在函数外部不能够使用。默认情况下函数参数中的闭包都为非逃逸闭包,这样做的优点是可以提高代码性能,节省内存消耗,开发者可以根据实际需求将闭包参数声明成逃逸闭包。

提示

非逃逸闭包也不可以作为返回值返回,如果这么做,编译器会抛出一个错误。

将闭包声明为非逃逸类型,需要使用@noescape修饰。需要注意的是,在最新版本的Xcode开发工具中,这个关键字已经不需要再使用,参数中的闭包默认都是非逃逸的,示例代码如下:

提示

逃逸类型的闭包常用于异步操作中,例如一个后台请求完成后要执行闭包回调,需要使用逃逸类型。

不是所有的闭包都需要显式创建,Swift语言中还有一种语法,其可以实现对简单闭包的自动生成,这种闭包通常称为自动闭包。需要注意,自动闭包参数的使用有严格的条件,首先此闭包不能够有参数,其次在调用函数传参时,此闭包的实现只能由一句表达式组成,闭包的返回值即为此表达式的值,自动闭包参数由@autoclosure来声明,示例代码如下:

自动闭包默认为非逃逸的,若要使用逃逸类型的闭包参数,需要声明如下:

    //将闭包参数声明为自动闭包,逃逸闭包
    func myFunc2(closure: @autoclosure @escaping ()->Bool)  {
    }