簡體   English   中英

[self] 如何在 Swift 上工作? 它的工作方式類似於 [unowned self] 或強參考

[英]How dose [self] work on Swift ? It work like [unowned self] or strong reference

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

它的作用如何?

[self] = [unowned self][self] = 強引用

通過捕獲子句捕獲變量:

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

將創建對 x 在創建閉包時引用的值的強捕獲。 見最后的例子。

如果您不使用捕獲子句,如

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")
}

output 是

>> 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)

如你看到的,

  • 不使用捕獲子句時,使用執行時的值(“已更改”)
  • 使用[b]時,會創建並輸出對“b”的強引用,因為 b 在創建時是“b”
  • 使用[weak c]時,會創建對 "c" 的弱引用; 由於 c 已更改為“更改 c”,舊的“c”被取消,因此捕獲被取消,output 為“c 為 nil”
  • 使用[unowned c]時相同,除了您的程序崩潰

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM