如果在内部使用延迟

时间:2019-07-11 11:29:20

标签: swift

仅当某些代码成功执行后,我想在函数退出后执行一些代码:

if object.open {
    defer {
        object.close()
    }
}
...
dome some stuff...
...
return
}

问题在于,在if条件之后立即执行延迟。据我了解,这是正确的行为。

然后的问题是: 可以在函数完成后在if内部推迟块代码。 我尝试了嵌套延迟,但是那没有用。 感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

通过使用defer,不可能直接将发生的事情推迟到当前作用域的末尾,例如您所处的if条件的发生。但是,有可能来无条件推迟并在defer中移动条件:

defer {
    if object.isOpen { object.close() }
}

更一般的解决方案如下:

var deferred: (() -> Void)? = nil
defer { deferred?() }
if object.isOpen {
    deferred = { object.close() }
}

这种更通用的解决方案将允许根据不同的条件推迟不同的事情,但显然一次最多只能推迟一次。要支持多个,您当然可以使用数组:

var deferred = [(() -> Void)]()
defer {
    for f in deferred.reversed() { f() }
}
if object1.isOpen {
    deferred.append { object1.close() }
}
if object2.isOpen {
    deferred.append { object2.close() }
}

但是,我强烈反对这样做,因为它会混淆代码流,并且似乎表明其他地方的设计不好。通常,使用defer的原因是当您在范围内有多种方式并且想要避免将相同的清理代码复制粘贴到所有代码上时,但是在这里您有多个清理路径。我会尝试隔离导致不同清理要求的路径。

答案 1 :(得分:0)

来自documentation

  

在将程序控制权转移到 defer语句出现的范围之前,使用defer语句执行代码。

因此,回答您的问题:

  

可以在函数完成后推迟if内部的块代码。

不。 defer会在其封闭范围结束时运行。