ios - defer 语句的不同行为

标签 ios swift

我在注销按钮上有代码,我在其中使用 defer 语句。

我想知道何时更改操作方法范围内的 defer 语句代码的位置。

  1. 我在方法末尾添加了 defer 语句,它向我显示警告。

'defer' statement before end of scope always executes immediately; replace with 'do' statement to silence this warning

代码:

override func sendButtonTapped(sender: Any) {

    self.deleteCoreData()
    self.clearUserDefaults()

    // Clear view context
    AppDelegate.shared.persistentContainer.viewContext.reset()

    ....
    ....

    // Call after all code execution completed in this block's Scope
    defer {
        // Set isUserLoggedIn and change root view controller.
        UserDefaults.Account.set(false, forKey: .isUserLoggedIn)
        AppDelegate.shared.setRootViewController()
    }
}
  • 然后,我在方法开始处添加了 defer 语句,它什么也没显示。
  • 代码:

    override func sendButtonTapped(sender: Any) {
    
        // Call after all code execution completed in this block's Scope
        defer {
            // Set isUserLoggedIn and change root view controller.
            UserDefaults.Account.set(false, forKey: .isUserLoggedIn)
            AppDelegate.shared.setRootViewController()
        }
    
        self.deleteCoreData()
        self.clearUserDefaults()
    
        // Clear view context
        AppDelegate.shared.persistentContainer.viewContext.reset()
    
        ....
        ....
    }
    

    谁能解释一下 defer 语句到底发生了什么?

    最佳答案

    总而言之,defer 语句将在您所在的范围末尾执行。( .apple doc : https://docs.swift.org/swift-book/ReferenceManual/Statements.html#grammar_defer-statement )

    来自苹果文档

    func f() {
        defer { print("First defer") }
        defer { print("Second defer") }
        print("End of function")
    }
    f()
    // Prints "End of function"
    // Prints "Second defer"
    // Prints "First defer"
    

    defer 语句允许您定义一个操作,该操作将在您想要完成的其余操作之后执行,即在结束时执行>范围

    警告也非常明确,考虑到您将 defer 语句放在作用域的末尾,它没有任何作用:

    func f() {
        print("TIC")
        defer { print("TAC") } // will be print at the end of the function
    }
    f()
    // Prints "TIC"
    // Prints "TAC""
    

    这与:

    完全相同
    func f() {
        print("TIC")
        print("TAC") // no defer, same result
    }
    f()
    // Prints "TIC"
    // Prints "TAC""
    

    走得更远

    那么为什么警告会建议您使用 do block ? 实际上,前面的两个示例并不是 100% 相同,当您使用 defer 语句时,它会创建自己的范围

    func f() {
        // here you are in the scope of the `f()` function
        print("TIC")
        defer { 
            // here you are the scope of the `defer` statement
            print("First defer") 
        }
    }
    

    手动创建作用域的最接近方法是 do 语句

    func f() {
        // here you are in the scope of the `f()` function
        print("TIC")
        do { 
            // here you are the scope of the `do` statement
            print("First defer") 
        }
    }
    

    来自苹果文档

    The do statement is used to introduce a new scope and can optionally contain one or more catch clauses, which contain patterns that match against defined error conditions. Variables and constants declared in the scope of a do statement can be accessed only within that scope.

    如果您想了解有关范围的更多信息,这里有一些讲座:https://andybargh.com/lifetime-scope-and-namespaces-in-swift/

    Essentially, an objects scope defines the areas of our program from which the item can be accessed.

    关于ios - defer 语句的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56472039/

    相关文章:

    ios - 使用 SwiftyJSON 处理 JSON 的示例

    ios - 为什么通过 UIImagePickerController 高和中设置选择的视频可以在结果上产生相同的质量属性?

    ios - setTorchModeOnWithLevel 不工作

    ios - Swift 中的双线性插值

    ios - UICollectionView 手势事件

    ios - 将 NSObject 转换为 double

    IOS 不在核心图形中显示替代颜色

    ios - Swift 是否可以为 MKLocalSearchRequest 和 MKLocalSearchResponse 设置一个特定的国家

    ios - 如何创建类似 IBInspectable 属性的段控件?

    ios - 这是我在 Swift 中不明白的一件事