首先了解一下@escaping 和 @noescape 的含义,在swift2中,你可能遇到过@noescape
属性,不过在swift3.0中已经被移除了(原因很简单:很简单,在swift3.0中@noescape
被用作一个默认值),替而换之的是@escaping。
逃逸的闭包理解:如果一个闭包被作为一个参数传递给一个函数,并且在函数return之后才被唤起执行,那么这个闭包是逃逸闭包。并且这个闭包的参数是可以“逃出”这个函数体外的。
可以看到requestAuthorization(_:)
方法接收了一个参数:一个闭包。在swift2中,闭包默认是可以“逃逸”到函数体外的,这就是为什么上面的例子没有报编译错误。注意completion作为一个参数传递给HKHealthStore 的requestAuthorizationToShareTypes(_:readTypes:completion:)
方法,这个方法是异步的,也就是说这个闭包会在requestAuthorization(_:)
函数return之后执行。换句话说,我们传给requestAuthorization(_:)
的这个闭包逃逸了,它已经逃逸出了这个函数体。
如果我们给requestAuthorization(_:)
函数参数添加一个@noescape
属性会变得非常有趣,下面是添加@noescape
属性的例子:
而在3.0中:编译提示:
enter之后:
PS::::这个@escaping
属性写在参数类型的前面而不是参数名称的前面。这是swift3里一个新的点。
所以@escaping的含义
这个提醒我们去理解@escaping
属性的含义。因为在swift3中闭包默认是不可逃逸的,逃逸闭包需要像这样被标记。@escaping
属性让我们可以那样做。
我们通过@escaping
属性标记闭包,编译错误就消失了。