defer是Swift中的一个特殊结构,允许在函数的作用域(scope)退出之前执行特定的代码块,无论是通过常规返回(return)还是错误(throw)退出。使用defer适合于释放资源,撤销更改或完成操作。
工作特点:
示例:
func testDefer() { print("begin") defer { print("first defer") } defer { print("second defer") } print("end") } // 输出: // begin // end // second defer // first defer
边界情况:
如果在函数内调用fatalError,所有的defer块是否都会被执行?
回答: 不,如果在函数中调用fatalError(或类似的不可控崩溃),所有通过defer延迟的块将不会执行。defer在应用程序崩溃的情况下不保证代码的调用。
示例:
func foo() { defer { print("Defer 1") } fatalError("Oops") defer { print("Defer 2") } } foo() // 不会输出任何内容,将导致崩溃
故事
在项目中使用defer关闭文件描述符。在出现错误时使用fatalError而不是正确的throw,导致打开的资源泄露,因为在崩溃时defer不会执行。
故事
在一个函数中有多个defer,其中一些依赖于局部变量的状态。开发者期望变量等于特定值,但在defer中,这个值被其他代码块改变了,导致在执行defer时使用了当前值而不是旧值,从而导致了错误的事务ID撤销。
故事
在嵌套的closure中写了defer块,以为它会在退出外部函数时执行。结果这个defer在退出closure时执行,而不是整个函数,资源被过早释放。