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





推荐阅读
  • 掌握DSP必备的56个核心问题,我已经将其收藏以备不时之需! ... [详细]
  • PHP连接MySQL的三种方法及预处理语句防止SQL注入的技术详解
    PHP连接MySQL的三种方法及预处理语句防止SQL注入的技术详解 ... [详细]
  • NOI题库(noi.openjudge.cn):1.7 编程基础之字符串 T31 至 T35 详解与解析
    T31至T35题目详细解析了字符串处理的基础编程技巧。其中,T31涉及P型编码,要求将一个仅包含数字字符的字符串转换为特定格式的编码串。例如,输入字符串“111223”应输出相应的P型编码结果。其他题目则涵盖了字符串的多种操作和变换方法,包括但不限于子串提取、字符替换和模式匹配等,旨在提升编程者对字符串处理的综合能力。 ... [详细]
  • 从 Java 过渡到 Ruby,不仅是一次编程语言的转换,更是一段技术进阶的旅程。本文将深入探讨两种语言在语法、生态系统和开发模式上的差异,帮助开发者顺利实现转型,并在新的环境中高效地编写高质量代码。 ... [详细]
  • 根据 Laravel 官方文档,视图文件在首次加载时会被编译成普通的 PHP 代码并存储在缓存中。当视图文件发生更改时,系统会自动检测到这些变化并重新编译和缓存新的版本,以确保用户始终看到最新的内容。这一机制显著提高了应用的性能和响应速度。 ... [详细]
  • 在VC环境中,掌握高效的调试技巧和高级应用对于提高开发效率至关重要。本文详细介绍了如何通过检查程序中的括号匹配来避免常见的语法错误。具体操作包括将光标置于待检测的括号(如大括号 {}、方括号 [] 和圆括号 ())上,系统会自动高亮显示对应的配对括号,从而帮助开发者快速定位和修复问题。此外,文章还探讨了其他实用的调试工具和方法,如断点设置、变量监视和调用堆栈分析,以全面提升代码调试的准确性和效率。 ... [详细]
  • 深入解析十大经典排序算法:动画演示、原理分析与代码实现
    本文深入探讨了十种经典的排序算法,不仅通过动画直观展示了每种算法的运行过程,还详细解析了其背后的原理与机制,并提供了相应的代码实现,帮助读者全面理解和掌握这些算法的核心要点。 ... [详细]
  • 使用Boost.Asio进行异步数据处理的应用程序主要依赖于两个核心概念:I/O服务和I/O对象。I/O服务抽象了操作系统接口,使得异步操作能够高效地执行。I/O对象则代表了具体的网络资源,如套接字和文件描述符,通过这些对象可以实现数据的读写操作。本文详细介绍了这两个概念在Boost.Asio中的应用及其在网络编程中的重要性。 ... [详细]
  • 根据不同环境需求,利用 Vue CLI 的 `npm run build` 命令对项目进行定制化打包,如测试、预发布和生产环境。通过配置 `process.env` 变量,实现不同环境下接口和服务的动态切换,确保应用在各阶段都能高效运行和调试。 ... [详细]
  • 深入解析 javax.faces.view.ViewDeclarationLanguageWrapper.getWrapped() 方法及其应用实例 ... [详细]
  • APKAnalyzer(1):命令行操作体验与功能解析
    在对apkChecker进行深入研究后,自然而然地关注到了Android Studio中的APK分析功能。将APK文件导入IDE中,系统会自动解析并展示其中各类文件的详细信息。官方文档提供了详细的命令行工具使用指南,帮助开发者快速上手。本文以一个RecyclerView的Adapter代理开源库为例,探讨了如何利用这些工具进行高效的APK分析。 ... [详细]
  • 深入解析Spring框架中的双亲委派机制突破方法
    在探讨Spring框架中突破双亲委派机制的方法之前,首先需要了解类加载器的基本概念。类加载器负责将类的全限定名转换为对应的二进制字节流。每个类在被特定的类加载器加载后,其唯一性得到保证。然而,这种机制在某些场景下可能会限制灵活性,因此Spring框架提供了一些策略来突破这一限制,以实现更加动态和灵活的类加载。这些策略不仅能够提升系统的可扩展性,还能在复杂的运行环境中确保类的正确加载和管理。 ... [详细]
  • Optimizing Profile URLs to Function Exclusively with Usernames, Eliminating the Need for User IDs ... [详细]
  • 本文深入分析了Django框架中模型应用与非模型应用的区别与应用场景,详细对比了两者在数据处理、性能表现及开发灵活性等方面的特点。同时,文章还介绍了如何在视图函数中有效利用这些特性,结合PostgreSQL、MySQL、SQLite3和Oracle等不同数据库的配置与使用方法,为开发者提供了全面的参考指南。 ... [详细]
  • 在非MFC项目中集成和应用MFC库的功能与优势
    在非MFC项目中集成和应用MFC库,可以充分利用MFC提供的丰富功能和优势。本文探讨了如何在不同类型的C++工程中(如Win32控制台应用程序、Win32项目等)引入MFC库,详细介绍了集成方法及其带来的性能提升和开发效率的提高。通过实例分析,展示了在非MFC项目中使用MFC库的具体步骤和注意事项。 ... [详细]
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社区 版权所有