为什么此Swift`defer`语句不能按预期工作?

dev*_*os1 3 swift

我试图理解该defer语句在Swift 2中的工作方式,因为我显然无法正确理解它。

我有一个postprocess()只应在view实例化时调用的方法:

internal func postprocess() {
    assert(self.node.isViewInstantiated()) // <- this is failing using the first method
    ...
}
Run Code Online (Sandbox Code Playgroud)

我最初试图这样称呼它:

public var view: UIView {
    get {
        if !node.isViewInstantiated() {
            defer {
                postprocess()
            }
        }
        return node.view // node.view getter creates view
    }
}
Run Code Online (Sandbox Code Playgroud)

但这引起了断言。当我将其更改为此时,它开始工作:

public var view: UIView {
    get {
        if node.isViewInstantiated() {
            return node.view
        } else {
            var result = node.view
            postprocess()
            return result
        }
}
Run Code Online (Sandbox Code Playgroud)

(因此请注意,这node.view是自我说明isViewIntantiated()。)

有人可以解释为什么defer实际上不延期吗?

nhg*_*rif 5

Swift的defer关键字在退出当前作用域时将要执行的块排队,这与函数返回时不一定相同。

一个defer内部块if,你离开的范围块将被执行if块。

您可以这样重写代码:

public var view: UIView {
    get {
        let shouldPostProcess = !node.isViewInstantiated
        defer {
            if shouldPostProcess {
                postprocess()
            }
        }
        return node.view // node.view getter creates view
    }
}
Run Code Online (Sandbox Code Playgroud)

它应该工作得很好。现在,defer-ed块的作用域为get方法调用并在返回时执行,在此之前,-ed块的作用域为if块并在if退出块作用域时执行。