Swift中@escaping的理解与使用

news2024/9/19 10:40:37

当我们在一个方法中将一个闭包当做参数的时候,那么就有很大概率用到这个@escaping关键字了,试想一般什么时候会将闭包当做参数传进来呢?很多时候比如方法里面有异步操作,需要方法先return,最后再调用闭包返回结果,如果直接通过return返回结果,那么传进来闭包也没什么用途了。

挑主要的说@escaping关键字修饰的闭包,意味着该闭包将在超出或离开你传递给它的作用域后仍然存在。也就是说这个闭包超出了方法的作用域,方法都return结束了,闭包还活着。
而没有被@escaping关键字修饰的闭包在方法结束的时候,也结束了自己。

首先先看一个没有@escaping关键字修饰的闭包。

func executeSomeRequest(_ closure: () -> Void) {
    closure()
}

上面这个方法是可以编译通过的,在executeSomeRequest方法中,直接调用了closure()闭包,然后方法执行完毕,闭包在方法的生命周期内执行完毕。

那么如果闭包没有在方法的生命周期内执行完毕,比如延迟执行闭包。

func executeSomeRequest(_ closure: () -> Void) {
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
        closure()
    }
}

结果得到下面的报错:
在这里插入图片描述
报错是因为编译器认为传入的闭包将会超出方法的作用域,如果我们将让闭包超出方法的作用域,则需要使用@escaping关键字修饰闭包,这种闭包很多人称之为“逃逸闭包”,同时也会告知方法调用者,这里的闭包会超出方法的作用域,需要注意点。

修改后:

func executeSomeRequest(_ closure: @escaping () -> Void) {
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
        closure()
    }
}

还有一种比较常用场景就是在请求数据的时候,比如下面这种:

func requestData(_ completion: @escaping (Data?, NetworkError?) -> Void) {
    URLSession.shared.dataTask(with: URLRequest(url: URL(string: "https://xxxx")!)) { data, response, error in
        if let data {
            completion(data, nil)
        } else {
            completion(nil, .feedError("something wrong"))
        }
    }
}

requestData方法中发送了请求出去,然后在数据回来后调用传入的completion闭包,那么这个completion闭包肯定超出了方法的作用域,所以必须得用@escaping修饰。

除了上面说的这种情况,还有一种情况,比如我们用一个属性将传入进来的闭包保存了,待某个时候再调用,比如下面的用法,如果不加@escaping关键字,肯定会报错。

func requestData2(_ completion: @escaping (Data?, NetworkError?) -> Void) {
    self.completion = completion
}

总而言之,@escaping告诉方法调用者,这个闭包的的存活时间比方法要长,在内存的某个地方存储着,需要注意循环引用和内存泄漏。

使用逃逸闭包的优缺点:
优点:@escaping闭包提供了处理异步任务和回调的灵活性,尤其是在异步编程中。
缺点:@escaping闭包可以捕获并保持引用,如果处理不当,它们可能会创建强引用循环,从而导致内存泄漏。

最后,希望能够帮助到有需要的朋友,如果觉得有帮助,还望点个赞,添加个关注,笔者也会不断地努力,写出更多更好用的文章。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1970247.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论数据驱动的优雅:构建轻量高效的数据中台-亿发

随着数据处理需求的不断增长,各类企业都在探索如何更高效地管理和利用数据。特别是在大规模数据应用的背景下,数据中台成为了众多企业优化数据管理的关键解决方案。从数据中台的建设需求到其实际应用,本文将详细解析数据中台的发展历程、建设…

.NET 一款反序列化打入冰蝎内存马的工具

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

用Python编写你的网络监控系统详解

概要 在现代网络管理中,实时监控网络流量和状态是保证网络正常运行的关键。使用Python编写网络监控工具可以帮助管理员及时发现和解决网络问题。本文将详细介绍如何使用Python编写网络监控工具,包括基本概念、常用库及其应用场景,并提供相应的示例代码。 网络监控的基本概念…

nginx反向代理严重错误[crit] (13: Permission denied) while reading upstream问题

nginx作为使用最广泛的一款反向代理软件,其性能也是非常优秀的,一般情况下,直接配置就可以使用,而且也都是稳定高效的,但是在实际应用中,对于不同的应用场景,总是会出现各种各样的问题&#xff…

nanopc-t4线刷Android10编译源码

文章目录 windows线刷Linux编译一撸到底核心编译命令最终Image目录源码和刷机工具放一个目录下线刷走一波,不能有任何报错windows线刷 https://www.myteamcloud.top/?p=266 Linux编译一撸到底 https://blog.csdn.net/wb4916/article/details/134911430 核心编译命令 ./b…

全网首创!基于GaitSet的一种多人步态识别方法公示

有源代码V细聊,可商用/私用/毕设等:NzqDssm16 🍉1 绪论 经过相关研究确认,步态识别是足以达到应用级别的生物识别技术,在现代社会中自始至终都存在着广泛的应用前景。之所以迟迟没有普及,主要是实…

docker配置阿里镜像加速器

‌阿里云镜像加速的核心功能是通过提供官方的镜像站点,加速官方镜像的下载。使用容器时,由于网络原因,下载‌Docker官方镜像可能会需要很长时间,甚至下载失败。阿里云容器镜像服务‌ACR(阿里云容器仓库)为此…

智慧大楼信息化一体化管理整体建设设计方案(可编辑80页PPT)

随着信息技术的飞速发展,智慧大楼已成为现代城市建设的重要趋势。本项目旨在通过信息化一体化管理整体建设设计方案,将大楼内的各个系统进行有机整合,实现智能化、高效化的管理与服务。通过该方案,我们期望提升大楼的运营效率、安…

【网络基础】初识网络 {计算机网络背景;网络协议初识;网络传输基本流程;网络中的地址管理;网络设备简单介绍}

一、计算机网络背景 1.1 网络发展 计算机网络的发展可以追溯到20世纪60年代,那时候最初的计算机网络只是为了让科学家们能够共享计算机资源和数据。但是在20世纪80年代,互联网的出现彻底改变了计算机网络的面貌,使得人们可以随时随地通过互…

昇思25天学习打卡营第XX天|Vision Transformer图像分类

好了👌到我最熟悉的模型了,苦苦缠斗几个月呜呜呜 CLIP预训练数据集薄纱了,这个对齐的思路很好,但是对文本图像长度限制更高,作者很可惜

详细分析nohup后台运行命令

目录 1. 基本知识2. Demo 1. 基本知识 Unix/Linux 命令,用于在后台运行程序,并确保它在用户退出或注销后继续运行 nohup 的主要作用是使程序在终端会话结束后继续运行,这对需要长时间执行的任务特别有用 基本的用法如下: nohu…

计算机网络课程介绍

计算机网络课程的核心内容与应用,涵盖多个关键协议与技术的深入理解,旨在全面培养学生的网络设计、分析及实际操作能力。以下是对该课程的严谨阐述: 一、课程核心原理与应用 本课程详尽阐述了IP协议簇的基本原理与应用,具体涵盖I…

Github 2024-08-02Java开源项目日报 Top9

根据Github Trendings的统计,今日(2024-08-02统计)共有9个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Java项目9Vue项目1Ruby项目1Java设计模式:提高开发效率的正规化实践 创建周期:3572 天开发语言:Java协议类型:OtherStar数量:86766 个Fork数…

ECCV 2024 | 深入探索GAN先验,哈工大、清华提出模型反演新方案

介绍 模型反演(MI)攻击的目的是利用输出信息从已发布的模型中重建隐私敏感的训练数据,这引起了人们对深度神经网络(DNNs)安全性的广泛关注。近年来,生成对抗网络(GANs)因其强大的图像…

4.Rabbon-微服务负载均衡

Rabbon-微服务负载均衡 1.Ribbon是什么1.1 基本概念1.2 主要功能1.3 负载均衡流程1.4 负载均衡策略 2.Ribbon如何使用2.1 基于配置文件的配置:2.2 基于注解的配置: 1.Ribbon是什么 Ribbon是Netflix发布的一个负载均衡器,它主要用于控制HTTP和…

PT4103B23F 白光LED升压转换器芯片IC

一般概述 PT4103是一款升压型DC/DC转换器,设计用于以恒流方式驱动单个锂离子电池中的多达8个串联的白光LED。由于PT4103直接调节输出电流,因此它非常适合驱动发光二极管(LED),其光强度与流经它们的电流成正比,而不是与它们…

Bugku-Web篇:Simple_SSTI_1

1.很简单的模板注入,直接f12查看源代码。 2.这里了解了一下什么是模板注入 这里针对的是flask模板,config是flask模板中的一个全局对象。包含了所有应用程序的配置值。 这里直接在url中写上 ?flag{{config.SECRET_KEY}}

力扣第四十八题——旋转图像

内容介绍 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9…

初识c++:stack和queue详解

本节大纲: #stack和queue详解# 1.容器适配器 2.stack的介绍和使用 2.1 stack的介绍 2.2 stack的使用 3.stack的模拟实现 4.queue的介绍和使用 4.1 queue的介绍 4.2 queue的使用 5.queue的模拟实现 6.priority_queue的介绍和使用 6.1 priority_queue的介绍…

什么是docker?小白也能看懂!

👏大家好!我是和风coding,希望我的文章能给你带来帮助! 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦 📝点击 我的主页 还可以看到和风的其他内容噢&#x…