【问题标题】:How dose [self] work on Swift ? It work like [unowned self] or strong reference[self] 如何在 Swift 上工作?它像 [unowned self] 或强引用一样工作
【发布时间】:2020-11-04 14:11:09
【问题描述】:

我知道 [weak self] 和 [unowned self] 但我不知道 [self]。

它的作用如何?

[self] = [unowned self] 要么 [self] = 强引用

【问题讨论】:

    标签: swift self self-reference


    【解决方案1】:

    通过捕获子句捕获变量:

    var closure = { [x] in x.doSomething() }
    

    将创建对 x 在闭包创建时所引用的值的强捕获。见最后的例子。

    如果你不使用像in这样的捕获子句

    var closure = { x.doSomething() }
    

    这将创建一个对 x 在闭包执行时引用的值的强引用。

    话虽如此,捕获 [self] 会创建一个强引用,但完全没有必要,除非您预计 self 会在某个时间点发生变化(这将是非常不寻常的)。


    示例

    class ValueClass {
        var value:String
        
        init (_ v:String)   { value = v }
        
        func info()         { print("\(value)") }
        deinit              { print ("deinit: \(value)") }
    }
    
    if (1==1) {
        print (">> No capture clause")
        var a:ValueClass? = ValueClass("a")
        let closure = { a != nil ? a!.info() : print("a is nil") }
        a = ValueClass("changed a")     // "deinit: a"
        closure()   // "a is nil"
        print ("<< done")
    }// "deinit: changed a"
    
    print ("------------------------------")
    
    if (1==1) {
        print (">> strong capture clause")
        var b:ValueClass? = ValueClass("b")
        let closure = { [b] in b != nil ? b!.info() : print("b is nil") }
        b = ValueClass("changed b")
        closure()                   // "b"
        print ("<< done")
    }                               // "deinit: b"; "deinit: changed b"
    
    print ("------------------------------")
    
    if (1==1) {
        print (">> weak capture clause")
        var c:ValueClass? = ValueClass("c")
        let closure = { [weak c] in c != nil ? c!.info() : print("c is nil") }
        c = ValueClass("changed c")     // "deinit: c"
        closure()                       // "c is nil"
        print ("<< done")
    }                                   // "deinit: changed c"
    
    print ("------------------------------")
    
    if (1==1) {
        print (">> unowned capture clause")
        var d:ValueClass? = ValueClass("d")
        let closure = { [unowned d] in d != nil ? d!.info() : print("d is nil") }
        d = ValueClass("changed d")     // "deinit: d"
        closure()   // error: Execution was interrupted, reason: signal SIGABRT.
        print ("<< done")
    }
    

    输出是

    >> No capture clause
    deinit: a
    changed a
    << done
    deinit: changed a
    ------------------------------
    >> strong capture clause
    b
    << done
    deinit: b
    deinit: changed b
    ------------------------------
    >> weak capture clause
    deinit: c
    c is nil
    << done
    deinit: changed c
    ------------------------------
    >> unowned capture clause
    deinit: d
    
    (CRASH)
    

    如你所见,

    • 当不使用捕获子句时,使用执行时的值(“changed a”)
    • 使用[b] 时,会创建并输出对“b”的强引用,因为b 在创建时是“b”
    • 使用[weak c] 时,会创建对“c”的弱引用;由于 c 已更改为“changed c”,旧的“c”被取消,因此捕获为 nill,输出为“c is nil”
    • 使用[unowned c] 时相同,只是您的程序崩溃了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-30
      • 2015-07-02
      • 2014-08-02
      • 1970-01-01
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多