Swift 为什么';这个快速的“延期”声明不是如预期的那样有效吗?

Swift 为什么';这个快速的“延期”声明不是如预期的那样有效吗?,swift,Swift,我试图理解Swift 2中的defer语句是如何工作的,因为我显然没有正确理解它 我有一个postprocess() internal func postprocess() { assert(self.node.isViewInstantiated()) // <- this is failing using the first method ... } 但这引发了断言。当我将其更改为此时,它开始工作: public var view: UIView { get

我试图理解Swift 2中的
defer
语句是如何工作的,因为我显然没有正确理解它

我有一个
postprocess()

internal func postprocess() {
    assert(self.node.isViewInstantiated()) // <- this is failing using the first method
    ...
}
但这引发了断言。当我将其更改为此时,它开始工作:

public var view: UIView {
    get {
        if node.isViewInstantiated() {
            return node.view
        } else {
            var result = node.view
            postprocess()
            return result
        }
}
(请注意,
node.view
是自实例化的,因此
isviewintated()


有人能解释一下为什么
延迟
实际上没有延迟吗?

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

当您离开
if
块的范围时,将执行
if
块内的
defer

您可以将代码重写为:

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

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

我明白了,这肯定解释了这一点。不幸的是,在我的例子中,这比简单地将
延迟
移动到外部要难一些,因为访问
节点.view
会实例化视图,因此对
isviewsinstantiated
的检查在那时总是返回true。但是我可以用一个Bool来解决这个问题。
public var view: UIView {
    get {
        let shouldPostProcess = !node.isViewInstantiated
        defer {
            if shouldPostProcess {
                postprocess()
            }
        }
        return node.view // node.view getter creates view
    }
}