美文网首页
Swift - defer的注意点

Swift - defer的注意点

作者: 健了个平_24 | 来源:发表于2021-08-13 03:14 被阅读0次

    defer:用来定义以任何方式(抛错误、return等)离开代码块前必须要执行的代码,这块代码将延迟至当前作用域结束之前执行。

    基本使用

    func test() {
        print("run test 1")
        
        defer {
            print("run defer")
        }
        
        print("run test 2")
    }
    
    // run test 1
    // run test 2
    // run defer
    

    注意点

    1. 一个函数中可以有多个defer,同一作用域的defer都是以栈的形式添加的,是以先进后出的顺序执行

    2. defer可以被阻拦添加(例如添加新defer前就 return 了)

    3. defer可以嵌套

      • 如果其中一层作用域的defer里面有多个子defer,那么这一层作用域结束之前,同样也是以先进后出的顺序去执行里面的子defer
    var isAdd = true
    
    func test() {
        print("run test 1")
        
        defer {
            print("run defer 5")
        }
        
        // defer可以嵌套
        defer {
            // 执行这一层作用域时同样也是以先进后出的顺序去执行里面的子defer
            defer {
                print("run defer 4")
            }
            
            defer {
                print("run defer 3")
            }
            
            print("run defer 2")
        }
    
        // defer可以被阻拦添加
        guard isAdd else { return }
        
        defer {
            print("run defer 1")
        }
        
        print("run test 2")
    }
    
    // isAdd == true
    // run test 1
    // run test 2
    // run defer 1
    // run defer 2
    // run defer 3
    // run defer 4
    // run defer 5
    
    // isAdd == false
    // run test 1
    // run defer 2
    // run defer 3
    // run defer 4
    // run defer 5
    
    1. defer除了可以访问当前作用域的任意变量,也可以访问所有外层作用域中的任意变量(最外层则是函数体)
      • 这些变量并不是copy过来的,而是有引用关系的,是真的把变量传过来的;
      • 而所有内层作用域中的变量都无法访问。
    func test() {
        defer {
            defer {
                defer {
                    defer {
                        let e = 5
                        d += 1
                        c += 1
                        b += 1
                        a += 1
                        // 可以访问当前和所有外层作用域的任意变量
                        print("a: \(a),", "b: \(b),", "c: \(c),", "d: \(d),", "e: \(e)")
                    }
                    var d = 4
                    c += 1
                    b += 1
                    a += 1
                }
                var c = 3
                b += 1
                a += 1
            }
            var b = 2
            a += 1
        }
        var a = 1
        // 无法访问内层作用域的变量
        // b += 1
    }
    
    // a: 5, b: 5, c: 5, d: 5, e: 5
    

    THE END.

    相关文章

      网友评论

          本文标题:Swift - defer的注意点

          本文链接:https://www.haomeiwen.com/subject/dhtdbltx.html