官术网_书友最值得收藏!

There's more...

The reference cycle problem can happen in situations other than relations between classes. When you use closure, there is a case where you may face a retain cycle. It happens when you assign a closure to a property in class instance and then this closure captures the instance. Let's consider the following example:

class HTMLElement { 
 
let name: String 
let text: String? 
 
lazy var asHTML: () -> String = { 
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 
    } 
} 
 
let heading = HTMLElement(name: "h1", text: "h1 title") 
print(heading.asHTML()) // <h1>h1 title</h1> 

We have the HTMLElement class, which has closure property asHTML. Then, we created an instance of that class which is heading, and then we called the closure to return HTML text. The code works fine, but as we said, it has a reference cycle. The instance set closure to one of its property, and the closure captures the instance (happens when we call self.name and self.text inside the closure). The closure in that case will retain self (have a strong reference to the heading instance), and at the same time, heading already has a strong reference to its property asHTML. To solve reference cycle made with closure, add the following line of code as first line in closure:

[unownedself] in 

So, the class will look like this:

class HTMLElement { 
 
let name: String 
let text: String? 
 
lazy var asHTML: () -> String = { 
 
        [unownedself] in 
 
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 
    } 
} 

The unowned keyword informs the closure to use a weak reference to self instead of the strong default reference. In that case, we break the cycle and everything goes fine.

主站蜘蛛池模板: 洞头县| 绥江县| 德保县| 盱眙县| 东莞市| 萨嘎县| 三明市| 专栏| 民丰县| 皮山县| 安徽省| 阿拉善右旗| 红安县| 仙桃市| 满洲里市| 新晃| 固始县| 乐至县| 固始县| 嘉峪关市| 苍梧县| 高淳县| 濮阳市| 阿拉善右旗| 邛崃市| 连山| 东丽区| 金塔县| 甘南县| 云南省| 临江市| 佛坪县| 岳阳市| 杨浦区| 灵寿县| 广安市| 双牌县| 澎湖县| 大关县| 邹平县| 嘉义县|