为什么这个Swift`defer`声明没有按预期工作?

时间:2016-02-24 00:39:31

标签: swift

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

我有一个postprocess()方法,只有在view实例化时才会被调用:

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

我原本试图像这样称呼它:

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

但是这引起了断言。当我把它改成它时,它开始工作:

public var view: UIView {
    get {
        if node.isViewInstantiated() {
            return node.view
        } else {
            var result = node.view
            postprocess()
            return result
        }
}

(请注意node.view是自我实例化的,因此isViewIntantiated()。)

有人可以解释defer实际上不推迟的原因吗?

1 个答案:

答案 0 :(得分:4)

当前范围退出时,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
    }
}

它应该完美无缺。现在,defer - ed块的范围限定为get方法调用,并在返回时执行,其前限为if块并作为if块执行范围退出。