热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Swift3中为何默认不自动关闭转义闭包,以及为何需明确使用“self”?

在Swift3中,默认情况下不自动关闭转义闭包的原因是为了避免潜在的内存管理和生命周期问题。明确使用“self”则是为了提高代码的可读性和安全性,确保开发者清楚地意识到闭包捕获了外部变量,从而避免意外的引用循环和资源泄漏。

在Swift 3中,默认情况下所有闭包都不转义

不,在Swift 3中,默认情况下仅闭包 函数参数
(即,函数本身就是函数输入)不转义(根据SE-0103)。例如:

class A {
let n = 5
var bar : () -> Void = {}
func foo(_ closure: () -> Void) {
bar = closure // As closure is non-escaping, it is illegal to store it.
}
func baz() {
foo {
// no explict 'self.' required in order to capture n,
// as foo's closure argument is non-escaping,
// therefore n is guaranteed to only be captured for the lifetime of foo(_:)
print(n)
}
}
}

由于closure在上面的示例中是不可转义的,因此禁止将其存储或捕获,因此将其生存期限制为该函数的生存期foo(_:)。因此,这意味着保证它捕获的任何值在函数退出后都不会保留—这意味着您不必担心捕获可能会发生的问题,例如保留周期。

然而,一个闭合件 存储的属性 (例如,bar在上面的例子)是由定义逸出(这将是无意义的与将其标记@noescape)作为它的寿命
限定于给定功能的-它(以及因此它的所有捕获的变量)将保持在只要给定实例保留在内存中即可。因此,这很容易导致诸如保留周期之类的问题,这就是为什么您需要使用一个显式self.的以便使捕获语义显式的原因。

实际上,举例来说,您的示例代码在viewDidLoad()被调用时会创建一个保留周期,因为它是一个存储属性,因此someclosure强烈地捕获selfself强烈引用someclosure了它。

值得注意的是,作为“存储的函数属性始终转义”规则的扩展,聚合中存储的函数(即具有关联值的结构和枚举)也总是转义,因为对此类聚合没有任何限制。正如pandaren
codemaster指出的那样, 当前 包括Optional–意味着Optional<() ->
Void>
(aka。(() -> Void)?)总是在逃避。鉴于可选参数已经建立在许多编译器魔术上,因此编译器最终可能会将其作为函数参数的特殊情况。


当然,您希望能够使用该@noescape属性的一个地方是闭包,该闭包是函数中的局部变量。只要不将其存储在函数外部或未被捕获,此类闭合将具有可预测的寿命。例如:

class A {
let n = 5
func foo() {
let f : @noescape () -> Void = {
print(n)
}
f()
}
}

不幸的@noescape是,这在Swift 3中已被删除,这是不可能的(有趣的是,在Xcode 8
GM中,这是可能的,但是会产生弃用警告)。正如JonShier所说,我们必须等待它重新添加到语言中,这可能会或可能不会发生。





推荐阅读
  • 在寻找轻量级Ruby Web框架的过程中,您可能会遇到Sinatra和Ramaze。两者都以简洁、轻便著称,但它们之间存在一些关键区别。本文将探讨这些差异,并提供详细的分析,帮助您做出最佳选择。 ... [详细]
  • 本文详细介绍了macOS系统的核心组件,包括如何管理其安全特性——系统完整性保护(SIP),并探讨了不同版本的更新亮点。对于使用macOS系统的用户来说,了解这些信息有助于更好地管理和优化系统性能。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • 中科院学位论文排版指南
    随着毕业季的到来,许多即将毕业的学生开始撰写学位论文。本文介绍了使用LaTeX排版学位论文的方法,特别是针对中国科学院大学研究生学位论文撰写规范指导意见的最新要求。LaTeX以其精确的控制和美观的排版效果成为许多学者的首选。 ... [详细]
  • 本文介绍了如何使用JavaScript的Fetch API与Express服务器进行交互,涵盖了GET、POST、PUT和DELETE请求的实现,并展示了如何处理JSON响应。 ... [详细]
  • 本文详细介绍了Grand Central Dispatch (GCD) 的核心概念和使用方法,探讨了任务队列、同步与异步执行以及常见的死锁问题。通过具体示例和代码片段,帮助开发者更好地理解和应用GCD进行多线程开发。 ... [详细]
  • 本文探讨了在iOS平台上开发BLE(蓝牙低功耗)应用程序时遇到的挑战,特别是如何实现应用在后台模式下仍能持续扫描并连接蓝牙设备。文章提供了具体的配置方法和常见的问题解决方案。 ... [详细]
  • iOS 开发技巧:TabBarController 自定义与本地通知设置
    本文介绍了如何在 iOS 中自定义 TabBarController 的背景颜色和选中项的颜色,以及如何使用本地通知设置应用程序图标上的提醒个数。通过这些技巧,可以提升应用的用户体验。 ... [详细]
  • 本文介绍如何在 Android 中通过代码模拟用户的点击和滑动操作,包括参数说明、事件生成及处理逻辑。详细解析了视图(View)对象、坐标偏移量以及不同类型的滑动方式。 ... [详细]
  • 尽管使用TensorFlow和PyTorch等成熟框架可以显著降低实现递归神经网络(RNN)的门槛,但对于初学者来说,理解其底层原理至关重要。本文将引导您使用NumPy从头构建一个用于自然语言处理(NLP)的RNN模型。 ... [详细]
author-avatar
真实的嘻嘻哈哈
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有