不同的闭合为保留周期提供了不同的结果

编程入门 行业动态 更新时间:2024-10-28 16:26:25
本文介绍了不同的闭合为保留周期提供了不同的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在阅读Apple的《 Swift编程语言指南》.在有关闭合的强引用循环的部分中,我尝试了另一种类型的闭合,但未给出预期的输出.

I am reading Apple's Swift Programming Language Guide. In the part about Strong Reference Cycle for closures, I tried a different type of closure but it did not give the expected output.

class HTMLElement { let name: String let text: String? lazy var asHTML : String = { //[unowned self] 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 } deinit { println("\(name) is being deinitialized") } } var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world") println(paragraph!.asHTML) paragraph = nil

此代码的输出是:

<p>hello, world</p> p is being deinitialized

即使没有[unown self],也会打印"p正在被初始化"

"p is being deinitialised" is printed even without [unowned self]

指南中的代码为:

class HTMLElement { let name: String let text: String? lazy var asHTML: () -> String = { [unowned self] 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 } deinit { println("\(name) is being deinitialized") } } var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world") println(paragraph!.asHTML) paragraph = nil

仅当添加[unown self]语句时,此命令才会显示取消初始化消息.

This prints the deinitialiser message only when the [unowned self] statement is added.

两个闭包之间有什么区别?

What is the difference between both the closures?

推荐答案

好问题!为了对其进行探索,我们应该将测试用例简化为证明它所需的最小数量:

Great question! To explore it, we should simplify the test case to the minimum required to demonstrate it:

// First case, a lazy string class LazyVar { let name = "LazyVar" lazy var lazyName : String = { return self.name }() deinit { println("\(name) is being deinitialized") } } var lazyVar: LazyVar? = LazyVar() println(lazyVar?.lazyName) lazyVar = nil // Calls deinit // Second case, a lazy ()->String class LazyFunc { let name = "LazyFunc" lazy var lazyFunc: () -> String = { // [unowned self] in // <-- This would break the loop return self.name } deinit { println("\(name) is being deinitialized") } } var lazyFunc: LazyFunc? = LazyFunc() println(lazyFunc?.lazyFunc()) lazyFunc = nil // Doesn't call deinit

在第一种情况下,没有永久的保留循环.当您访问lazyName时,闭包将被评估为{ return self.name }.该闭包捕获self,计算一个字符串,然后返回该字符串.该字符串已分配给属性.现在,我们已经完成了关闭,因此已将其释放,并释放了self.请注意,这里有一个简短的保留循环,但是没关系.最终它被打破了,这就是一切.

In the first case, there is no permanent retain loop. When you access lazyName, a closure is evaluated { return self.name }. That closure captures self, computes a string, and returns the string. The string is assigned to the property. We're now done with the closure, so it's released, and it releases self. Note that there is a brief retain loop here, but that's ok. It is eventually broken, and that's all that matters.

在第二种情况下,存在一个永久的保留循环.当您访问lazyFunc()时,它将调用一个闭包,该闭包将创建一个新闭包.该新的闭包是{return self.name},并且已分配给该属性.而且该闭包保留self,因此永不中断的保留循环也是如此.将[unowned self] in添加到lazyFunc中,将为您打破循环.

In the second case, there is a permanent retain loop. When you access lazyFunc(), it calls a closure that creates a new closure. That new closure is {return self.name}, and that is assigned to the property. And that closure retains self, so is a retain loop that is never broken. Adding [unowned self] in to lazyFunc as marked would break the loop for you.

更多推荐

不同的闭合为保留周期提供了不同的结果

本文发布于:2023-11-26 23:57:02,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1635725.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:周期

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!