热门标签 | 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所说,我们必须等待它重新添加到语言中,这可能会或可能不会发生。





推荐阅读
  • PHP函数的工作原理与性能分析
    在编程语言中,函数是最基本的组成单元。本文将探讨PHP函数的特点、调用机制以及性能表现,并通过实际测试给出优化建议。 ... [详细]
  • 小编给大家分享一下Vue3中如何提高开发效率,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获, ... [详细]
  • 第六章:枚举类型与switch结构的应用分析
    第六章深入探讨了枚举类型与 `switch` 结构在编程中的应用。枚举类型(`enum`)是一种将一组相关常量组织在一起的数据类型,广泛存在于多种编程语言中。例如,在 Cocoa 框架中,处理文本对齐时常用 `NSTextAlignment` 枚举来表示不同的对齐方式。通过结合 `switch` 结构,可以更清晰、高效地实现基于枚举值的逻辑分支,提高代码的可读性和维护性。 ... [详细]
  • 洛谷 P4009 汽车加油行驶问题 解析
    探讨了经典算法题目——汽车加油行驶问题,通过网络流和费用流的视角,深入解析了该问题的解决方案。本文将详细阐述如何利用最短路径算法解决这一问题,并提供详细的代码实现。 ... [详细]
  • OBS Studio自动化实践:利用脚本批量生成录制场景
    本文探讨了如何利用OBS Studio进行高效录屏,并通过脚本实现场景的自动生成。适合对自动化办公感兴趣的读者。 ... [详细]
  • 本文探讨了在SQL Server中处理几何类型列时遇到的INTERSECT操作限制,并提供了解决方案,包括通过转换数据类型和使用额外表结构的方法。 ... [详细]
  • 深入理解Java SE 8新特性:Lambda表达式与函数式编程
    本文作为‘Java SE 8新特性概览’系列的一部分,将详细探讨Lambda表达式。通过多种示例,我们将展示Lambda表达式的不同应用场景,并解释编译器如何处理这些表达式。 ... [详细]
  • Logging all MySQL queries into the Slow Log
    MySQLoptionallylogsslowqueriesintotheSlowQueryLog–orjustSlowLog,asfriendscallit.However,Thereareseveralreasonstologallqueries.Thislistisnotexhaustive:Belowyoucanfindthevariablestochange,astheyshouldbewritteninth ... [详细]
  • 在将 Android Studio 从 3.0 升级到 3.1 版本后,遇到项目无法正常编译的问题,具体错误信息为:org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:processDemoProductDebugResources'。 ... [详细]
  • 本文详细介绍了Elasticsearch中的分页查询机制,包括基本的分页查询流程、'from-size'浅分页与'scroll'深分页的区别及应用场景,以及两者在性能上的对比。 ... [详细]
  • 在Java开发中,保护代码安全是一个重要的课题。由于Java字节码容易被反编译,因此使用代码混淆工具如ProGuard变得尤为重要。本文将详细介绍如何使用ProGuard进行代码混淆,以及其基本原理和常见问题。 ... [详细]
  • PostgreSQL 12 版本预览:分离 max_wal_senders 和 max_connections 的连接槽处理
    本文介绍了 PostgreSQL 12 中的一项重要改进,即 max_wal_senders 参数不再计入 max_connections,从而解决了流复制连接槽不足的问题。 ... [详细]
  • 开发技巧:在Interface Builder中实现UIButton文本居中对齐的方法与步骤
    开发技巧:在Interface Builder中实现UIButton文本居中对齐的方法与步骤 ... [详细]
  • [译]  OS X 和 iOS 的测绘框架Core Plot 入门教程
    [译] OS X 和 iOS 的测绘框架Core Plot 入门教程 ... [详细]
  • 当前,众多初创企业对全栈工程师的需求日益增长,但市场中却存在大量所谓的“伪全栈工程师”,尤其是那些仅掌握了Node.js技能的前端开发人员。本文旨在深入探讨全栈工程师在现代技术生态中的真实角色与价值,澄清对这一角色的误解,并强调真正的全栈工程师应具备全面的技术栈和综合解决问题的能力。 ... [详细]
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社区 版权所有