一尘不染

Swift 1.2中的@noescape属性

swift

Swift 1.2中有一个新属性,函数中带有闭包参数,如文档所述:

这表明该参数仅被调用(或在调用中作为@ noescape参数传递),这意味着它不能超过调用的生命周期。

以我的理解,在此之前,我们可以[weak self]不让闭包强烈引用其类,而self可以为nil或执行闭包时的实例,但是现在,这@noescape意味着闭包将永远不会执行如果该课程取消了初始化。我理解正确吗?

如果我是@noescape对的,当它们的行为非常相似时,为什么要使用由常规函数插入的闭包呢?


阅读 234

收藏
2020-07-07

共1个答案

一尘不染

@noescape 可以这样使用:

func doIt(code: @noescape () -> ()) {
    /* what we CAN */

    // just call it
    code()
    // pass it to another function as another `@noescape` parameter
    doItMore(code)
    // capture it in another `@noescape` closure
    doItMore {
        code()
    }

    /* what we CANNOT do *****

    // pass it as a non-`@noescape` parameter
    dispatch_async(dispatch_get_main_queue(), code)
    // store it
    let _code:() -> () = code
    // capture it in another non-`@noescape` closure
    let __code = { code() }

    */
}

func doItMore(code: @noescape () -> ()) {}

添加@noescape保证闭包不会存储在某个地方,以后使用或异步使用。

从调用者的角度来看,无需关心捕获变量的生存期,因为它们是在调用函数中使用还是根本不使用。另外,我们可以使用隐式self,从而避免键入self.

func doIt(code: @noescape () -> ()) {
    code()
}

class Bar {
    var i = 0
    func some() {
        doIt {
            println(i)
            //      ^ we don't need `self.` anymore!
        }
    }
}

let bar = Bar()
bar.some() // -> outputs 0

另外,从编译器的角度来看(如发行说明中所述):

这样可以进行一些次要的性能优化。

2020-07-07