循环强引用还会发生在当你将一个闭包赋值给类实例的某个实例,并且这个闭包体中又实用了这个类实例。这个闭包体重可能访问了实例的某个属性,例如self.**,或者闭包中调用了实例的某个方法,例如self.**,这两种情况都导致闭包“捕获”self,从而产生了循环强引用。

  循环强引用的产生,是因为闭包和类相似,都是引用类型。当你把闭包赋值给某个属性时,你也把一个引用赋值给了这个闭包。实质上,这跟之前的问题一样,两个强引用让彼此一直有效。但是,和两个类实例不同,这次一个是类实例,另一个是闭包。

  Swift提供了一种优雅的方法来解决这个问题,称之为闭包捕获列表。

  在定义闭包时,同时定义捕获列表作为闭包的一部分,通过这种方式可以解决闭包和类实例之间的循环强引用。捕获列表定义了闭包体内捕获一个或者多个引用类型的规则。跟解决两个类实例间的循环强引用一样,声明每个捕获的引用为弱引用或无主易用,而不是强引用。应该根据代码关系来决定使用弱引用还是无主引用。

  ----------定义捕获列表

  捕获列表中的每一项都由一对元素组成,一个元素是weak或unowned关键字,另一个元素是类实例的引用(如self)或初始化过的变量(如delegate = self.delegate!)。这些项在方括号中用逗号分开。

  如果闭包有参数列表和返回类型,把捕获列表放在它们前面:

  如果闭包没有指明参数列表或者返回类型,即他们会通过上下文来判断,那么可以把捕获列表和关键字in放在闭包最开始的地方。

  ----------弱引用和无主引用

  在闭包和捕获的实例总是互相引用时并且总是同时销毁时,将闭包内的捕获定义为无主引用。

  相反的,在被捕获的引用可能会变为nil时,将闭包内的捕获定义为弱引用。弱引用总是可选类型,并且当引用的实例被销毁后,弱引用的值会自动置为nil。这使我们可以在闭包体内检查他们是否存在。

  注意:如果被捕获的引用绝对不会变为nil,应该用无主引用,而不是弱引用。

class HTMLElement {
let name:String
let text:String? lazy var asHTML:Void -> String = {
[unowned self] in //表示“用无主引用而不是强引用来捕获 self ”
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")
}
} var paragraph:HTMLElement? = HTMLElement(name: "p", text: "hello world")
print(paragraph!.asHTML())

  打印:

<p> hello world<p>

这个闭包这个地方,没有看懂。

最新文章

  1. 【Winform】使用BackgroundWorker控制进度条显示进度
  2. 轻量、强大的代码编辑器控件-WinForm完美版
  3. 怎样设置才能允许外网访问MySQL
  4. 《深入浅出JavaScript》
  5. ado.net数据库操作(1)
  6. 測试之路3——对照XML文件2
  7. 【jsp/servlet】 javaweb中的一些简单问题整理
  8. 在 ASP.NET Core 项目中实现小写的路由URL
  9. 百度APP移动端网络深度优化实践分享(二):网络连接优化篇
  10. Texture转Texture2D
  11. SpringMVC统一转换null值为空字符串的方法 !
  12. 【转载】 强化学习(七)时序差分离线控制算法Q-Learning
  13. 让Visual Studio载入Symbol(pdb)文件
  14. sqlite3获取所有表信息
  15. 4、线程范围内的数据共享之ThreadLocal
  16. maven配置src/resources默认目录
  17. UVA-11029 Leading and Trailing
  18. PHP 自动加载的简单实现(推荐)
  19. 记录使用jQuery和Python抓取采集数据的一个实例
  20. Zabbix Server端配置文件

热门文章

  1. 【COGS &amp; USACO】896. 圈奶牛(凸包)
  2. sqlserver行列转换
  3. Linux命令总结_文件查找之grep
  4. QRadioButton 使用方法
  5. 记sql语句空格带来的问题
  6. wordpress安装
  7. ASP.NET开发中主要的字符验证方法-JS验证、正则表达式、验证控件、后台验证
  8. lucene 建立索引的过程
  9. Javascript 笔记与总结(2-10)删除节点,创建节点
  10. PHP 开发 APP 接口 学习笔记与总结 - APP 接口实例 [6] 版本升级接口开发