保证在Swift中调用“延迟”吗?

时间:2016-01-30 22:59:09

标签: ios swift

根据Apple Swift文档推迟

  

此语句允许您执行任何必须执行的清理,无论执行如何离开当前代码块,无论它是因为抛出错误还是由于返回或中断等语句而离开。

documentation

但是这段代码:

enum SomeError: ErrorType {
    case BadLuck
}

func unluckey() throws {
    print("\n\tunluckey() -> someone will have a bad day ;)\n")
    throw SomeError.BadLuck
}

func callsUnluckey() throws {

    print("callsUnluckey() -> OPENING something")
    defer {
        print("callsUnluckey() -> CLOSEING something")
    }

    print("callsUnluckey() -> WORKING with something")

    try unluckey()
    print("callsUnluckey() -> will never get here so chill...")

    defer {
        print("callsUnluckey() -> why this is not getting called?")
    }
}

do {
    try callsUnluckey()
} catch {
    print("")
    print("someone had a bad day")
}

在控制台中生成此结果:

callsUnluckey() -> OPENING something
callsUnluckey() -> WORKING with something

    unluckey() -> someone will have a bad day ;)

callsUnluckey() -> CLOSEING something

someone had a bad day 

我的问题是:为什么callUnluckey()的最后一次推迟没有被调用?

1 个答案:

答案 0 :(得分:4)

查看The Swift Programming Language中汇总的语言语法:defer是一个语句。在语法中,语句是必须按顺序运行的命令(与程序元素的定义相反,如类或函数,稍后将在命令式代码中使用)。

请注意在您引用的部分之后的位,依赖于顺序。如果defer只是一个声明,如函数或属性或类型声明,则不会有排序效果。 (例如,将函数声明放在什么顺序并不重要。)

IIRC(现在在移动设备上,不能轻易检查),如果你在defer之后放置return,编译器会抓住你,注意它是永远不会被执行的代码。

请记住,Swift中的“投掷”实际上只是一种特殊的返回类型。因此,如果您的函数throw s,throw之后的代码将不会被执行(因此没有defer语句将能够设置代码块以便稍后执行)。当你声明一个函数throws时,对其他抛出函数的任何调用都会有效地成为一个可能的throw语句,它本身就是一个返回。