[英]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
在閉包中不為人所知有關,但是對於尚未創建self
的init
方法來說,這不是相同的情況嗎?
其次,這個代碼示例中的強引用循環究竟在哪里,是否是self
強烈引用asHTML
,如果是的話,導致循環的強引用的第二部分在哪里?
第三,當常量不能改變值(從nil
到一個值再回到nil
)時,為什么常量text
屬性是可選的?
最后,參數text: String? = nil
是什么意思text: String? = nil
text: String? = nil
在init
方法用於接受用戶發送的參數時init
方法?
對不起,這個長問題,我只是對閉包強引用循環感到困惑......盡管我確實理解類屬性和類實例之間的強引用循環。
1
lazy
用於僅在調用時創建的屬性。 所以在你調用myClass.myLazyAttribute
之前它不會占用任何空間。 這也意味着它將在類初始化后進行初始化,這非常有用。
在這種情況下, lazy
用於訪問self
,就像您所說的那樣,因為self
在實例初始化之前不可用。
2
閉包捕獲其中使用的值。 在這種情況下,它捕獲self
。 它不會在 A 類和 B 類之間創建強引用循環,而是在其自身和閉包之間創建強引用循環。 如果你想象閉包內部的操作需要很長時間,那就更有意義了。 在執行過程中發生了其他事情,您想取消初始化該實例。 但是閉包已經捕獲了self
並且它會保持實例活着直到它完成。
通過在[unowned self] in
unowned [unowned self] in
使用[unowned self] in
您可以在閉包運行時再次取消初始化實例。 雖然這會使您的應用程序崩潰。
關於此特定用途的好信息: 鏈接
在閉包的特定情況下,您只需要意識到在它內部引用的任何變量都由閉包“擁有”。 只要閉包在附近,這些對象就可以保證在附近。 阻止這種所有權的唯一方法,就是做[無主的自己]或[弱小的自己]。
強引用循環本質上是什么:
或者更短:實例的引用計數高於可訪問引用的數量。
在這種情況下, 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.