簡體   English   中英

對關閉強引用循環感到困惑?

[英]Confused on closure strong reference cycle?

class HTMLElement {

    let name : String
    let text: String?

    //Declaring a lazy variable that has a strong reference to this closure
    lazy var asHTML: Void -> String = {
        //Optional binding here
        if let text = self.text {
             return "<\(self.name)>\(text)<\(self.name)>"
        } else {
            return "<\(self.name) >"
        }
    }

    init(name: String, text: String? = nil){
        self.name = name
        self.text = text
    }

    deinit {
        print("\(name) is being deinitialized")
    }
}

我的問題是:為什么閉包聲明為 Lazy,我知道這與self在閉包中不為人所知有關,但是對於尚未創建selfinit方法來說,這不是相同的情況嗎?

其次,這個代碼示例中的強引用循環究竟在哪里,是否是self強烈引用asHTML ,如果是的話,導致循環的強引用的第二部分在哪里?

第三,當常量不能改變值(從nil到一個值再回到nil )時,為什么常量text屬性是可選的?

最后,參數text: String? = nil是什么意思text: String? = nil text: String? = nilinit方法用於接受用戶發送的參數時init方法?

對不起,這個長問題,我只是對閉包強引用循環感到困惑......盡管我確實理解類屬性和類實例之間的強引用循環。

1

lazy用於僅在調用時創建的屬性。 所以在你調用myClass.myLazyAttribute之前它不會占用任何空間。 這也意味着它將在類初始化后進行初始化,這非常有用。

在這種情況下, lazy用於訪問self ,就像您所說的那樣,因為self在實例初始化之前不可用。

2

代碼所在的蘋果文檔。

閉包捕獲其中使用的值。 在這種情況下,它捕獲self 它不會在 A 類和 B 類之間創建強引用循環,而是在其自身和閉包之間創建強引用循環。 如果你想象閉包內部的操作需要很長時間,那就更有意義了。 在執行過程中發生了其他事情,您想取消初始化該實例。 但是閉包已經捕獲了self並且它會保持實例活着直到它完成。

通過在[unowned self] in unowned [unowned self] in使用[unowned self] in您可以在閉包運行時再次取消初始化實例。 雖然這會使您的應用程序崩潰。

關於此特定用途的好信息: 鏈接

在閉包的特定情況下,您只需要意識到在它內部引用的任何變量都由閉包“擁有”。 只要閉包在附近,這些對象就可以保證在附近。 阻止這種所有權的唯一方法,就是做[無主的自己]或[弱小的自己]。

強引用循環本質上是什么:

  • 你有一個類的實例
  • 實例的引用計數大於 0
  • 不再有對您的程序可用的實例的引用。

或者更短:實例的引用計數高於可訪問引用的數量。

在這種情況下, self的引用計數增加 1,因為它被閉包捕獲。 我們不能訪問那個引用,因為我們不能說: closure.selfAttribute ,所以我們不能把它設置為nil 只有當關閉完成時,引用計數才會再次減少 1。

3

它是一個可選的常量,但它的初始值是在類的 init 方法中設置的。 所以它可以在 init 方法中接收一個值,但它是不可變的。 這稱為延遲初始化

4

這是一個具有默認值的函數參數。

func someFunction(myParamWithDefaultValue : Int = 10) {
    print(myParamWithDefaultValue)
}

someFunction() // 10
someFunction(5) // 5

暫無
暫無

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

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