Swift 开发教程系列 - 第11章:内存管理和 ARC(Automatic Reference Counting)
在 Swift 中,内存管理由 ARC(自动引用计数)机制自动处理。ARC 通过追踪和管理对象的引用计数来确保分配的内存得到有效释放。尽管 ARC 在大多数情况下能够高效地管理内存,但理解其工作原理仍然十分重要,因为不当的引用会导致内存泄漏或循环引用。本章将介绍 ARC 的基本原理、强引用和弱引用的使用、循环引用的识别和解决方法。
11.1 ARC 基础
ARC 主要用于引用类型(即类)的内存管理。每个类实例在分配时,ARC 会分配一块内存用于存储该实例的所有属性和方法。当一个实例的引用计数变为零时,ARC 自动释放该实例的内存。
示例代码
class Person {let name: Stringinit(name: String) {self.name = nameprint("\(name) is initialized")}deinit {print("\(name) is being deinitialized")}
}var person1: Person? = Person(name: "Alice")
person1 = nil // 当 person1 被赋值为 nil 时,ARC 会释放该内存
在上例中,当 person1 被设置为 nil 后,Person 实例的引用计数变为零,ARC 自动释放该对象并调用 deinit 方法。
11.2 强引用
在 Swift 中,默认情况下,所有的引用都是强引用(strong reference),意味着对象的引用计数会增加。当多个强引用指向同一个对象时,该对象的引用计数会随着引用的增加而增加,只有在所有引用都被移除后,引用计数才会为零,ARC 才会释放对象。
示例代码
class Car {let model: Stringinit(model: String) {self.model = model}
}var car1: Car? = Car(model: "Tesla")
var car2 = car1 // car1 和 car2 都指向同一个 Car 实例
car1 = nil
// car2 仍然持有该实例,因此实例不会被释放
在上例中,即使 car1 被设置为 nil,car2 仍然持有对 Car 实例的强引用,因此该实例不会被释放。
11.3 弱引用和无主引用
为了解决循环引用问题,Swift 提供了 weak(弱引用)和 unowned(无主引用)两种解决方案。
- 弱引用(weak):适用于可能在生命周期中变为 nil 的对象。弱引用不会增加引用计数,因此当没有其他强引用时,对象会被释放。
- 无主引用(unowned):适用于生命周期中不会变为 nil 的对象。无主引用不会增加引用计数,但对象被释放后,如果仍然访问无主引用,会导致程序崩溃。
示例代码
class Owner {let name: Stringvar pet: Pet?init(name: String) {self.name = name}deinit {print("\(name) is being deinitialized")}
}class Pet {let name: Stringweak var owner: Owner? // 使用 weak 解决循环引用init(name: String) {self.name = name}deinit {print("\(name) is being deinitialized")}
}var alice: Owner? = Owner(name: "Alice")
var fluffy: Pet? = Pet(name: "Fluffy")
alice?.pet = fluffy
fluffy?.owner = alicealice = nil // "Alice is being deinitialized"
fluffy = nil // "Fluffy is being deinitialized"
在上例中,Owner 和 Pet 类存在循环引用。通过将 owner 属性声明为弱引用,解决了循环引用问题,使 Owner 和 Pet 可以正确释放。
11.4 闭包和循环引用
闭包在捕获对象时会创建强引用,可能导致循环引用。为了解决这个问题,可以在闭包中使用捕获列表(capture list)指定弱引用或无主引用。
示例代码
class HTMLElement {let name: Stringlet text: String?lazy var asHTML: () -> String = { [weak self] inguard let self = self else { return "" }return "<\(self.name)>\(self.text ?? "")</\(self.name)>"}init(name: String, text: String? = nil) {self.name = nameself.text = text}deinit {print("\(name) is being deinitialized")}
}var paragraph: HTMLElement? = HTMLElement(name: "p", text: "Hello, world!")
print(paragraph?.asHTML() ?? "")
paragraph = nil // "p is being deinitialized"
在上例中,通过 [weak self] 捕获列表防止闭包对 self 创建强引用,避免了循环引用。
11.5 常见的 ARC 内存管理误区
- 过度使用强引用:所有对象都默认使用强引用,但在合适的地方应使用弱引用以避免循环引用。
- 滥用无主引用:无主引用适用于不会变为 nil 的对象,否则会导致崩溃。
- 闭包导致的循环引用:闭包中对 self 的隐式强引用是循环引用的常见原因,使用捕获列表可以避免此问题。
11.6 ARC 优化实践
-
分析引用关系:在设计类之间的引用关系时,避免循环引用的结构,适当地使用 weak 或 unowned 关键字。
-
善用工具:Xcode 提供了内存图和 Instruments 工具,可以帮助检测内存泄漏和循环引用。
-
定期释放对象:在可能产生强引用的地方(如闭包、异步操作等),确认对象在使用后被正确释放。
通过本章的学习,你掌握了 Swift 中的内存管理基础,包括 ARC 的工作原理、强引用和弱引用的使用、以及如何避免循环引用。合理的内存管理对提高应用性能和稳定性至关重要。下一章将介绍 Swift 的高级特性之一:协议和协议扩展,用于构建更具灵活性和扩展性的代码结构。
相关文章:
Swift 开发教程系列 - 第11章:内存管理和 ARC(Automatic Reference Counting)
在 Swift 中,内存管理由 ARC(自动引用计数)机制自动处理。ARC 通过追踪和管理对象的引用计数来确保分配的内存得到有效释放。尽管 ARC 在大多数情况下能够高效地管理内存,但理解其工作原理仍然十分重要,因为不当的引用…...
C#中 layout的用法
在C#中,layout并不是一个直接用于C#语言本身的关键字或特性。然而,layout在与C#紧密相关的某些上下文中确实有其用途,特别是在涉及用户界面(UI)设计和数据展示时。以下是几个常见的与layout相关的用法场景:…...
【编程概念基础知识】
、编程基础 一、面向对象的三大特性 1、封装: 盒子、零件、按钮 隐藏对象 的内部状态,并且只通过对象的方法来访问数据 想象你有一个小盒子(这个盒子就是一个类),里面装着一些零件(这些零件就是数据&a…...
【React】深入理解 JSX语法
🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 💫个人格言: "如无必要,勿增实体" 文章目录 深入理解 JSX语法1. JSX 简介2. JSX 的基本语法2.1 基本结构2.2 与普通 JavaScr…...
【Linux】从零开始使用多路转接IO --- 理解EPOLL的 LT水平触发模式 与 ET边缘触发模式
当你偶尔发现语言变得无力时, 不妨安静下来, 让沉默替你发声。 --- 里则林 --- 从零开始认识多路转接 1 EPOLL优缺点2 EPOLL工作模式 1 EPOLL优缺点 poll 的优点(和 select 的缺点对应) 接口使用方便:虽然拆分成了三个函数,…...
QtLua
描述 QtLua 库旨在使用 Lua 脚本语言使 Qt4/Qt5 应用程序可编写脚本。它是 QtScript 模块的替代品。 QtLua 不会为 Qt 生成或使用生成的绑定代码。相反,它提供了有用的 C 包装器类,使 C 和 lua 对象都可以从 lua 和 C 访问。它利用 Qt 元对象系统将 QOb…...
c++-有关计数、双变量累加、半衰、阶乘、变量值互换的基础知识
C是一种非常强大和灵活的编程语言,它包含了许多重要的概念和技巧。在本文中,我们将重点讨论五个主题:计数、双变量累加、半衰、阶乘和变量值的互换。我们将介绍这些概念的定义、用法、题目、答案和解释,以帮助读者更好地理解和运用…...
MyBatis3-获取参数值的方式、查询功能及特殊SQL执行
目录 准备工作 获取参数值的方式(重点) 查询功能 查询一个实体类对象 查询一个list集合 查询单个数据 查询一条数据为map集合 查询多条数据为map集合 特殊SQL执行 模糊查询 批量删除 动态设置表名 添加功能获取自增的主键 准备工作 模块My…...
web——[SUCTF 2019]EasySQL1——堆叠注入
这个题主要是讲述了堆叠注入的用法,来复现一下 什么是堆叠注入 堆叠注入:将多条SQL语句放在一起,并用分号;隔开。 1.查看数据库的名称 查看数据库名称 1;show databases; 发现有名称为ctftraining的数据库 2.对表进行查询 1;show tabl…...
【Ubuntu学习】Ubuntu无法使用vim命令编辑
问题 在VMware首次安装Ubuntu,使用vi指令对文件进行编辑,按i键后无法更改文件内容。 原因 由于Ubuntu中预装的是vim-tiny,平时开发中需要使用vim-full。 解决方案 卸载预装vim sudo apt-get remove vim-common安装vim-full sudo apt-get …...
UniAPP u-popup 禁止背景滑动
增加class .NoScroll {overflow: hidden;position: fixed; }在外层div上增加该class判断条件...
F5全新报告揭示AI时代API安全面临严峻挑战
F5 《2024年应用策略现状报告:API安全》揭示了 API 保护中的漏洞以及对全面安全措施的迫切需求 西雅图,2024年11月11日 – F5(NASDAQ: FFIV)日前发布《2024年应用策略现状报告:API 安全》(以下简称为“报告”),揭示了跨行业API安全面临的严峻现状。该报告强调了企业API保护方面…...
使用C语言进行信号处理:从理论到实践的全面指南
1. 引言 在现代操作系统中,信号是一种进程间通信机制,它允许操作系统或其他进程向一个进程发送消息。信号可以用来通知进程发生了一些重要事件,如用户请求终止进程、硬件异常、定时器超时等。掌握信号处理技术对于开发健壮、高效的系统程序至…...
什么是工单管理系统?全面认识指南
在现代企业中,客户服务和支持是业务成功的关键因素之一。为了有效地管理客户请求和问题,许多公司采用了工单管理系统。本文将深入探讨工单管理系统的定义、功能、优势。 一、工单管理系统的定义 工单管理系统是一种软件工具,旨在帮助企业管…...
集群化消息服务解决方案
目录 集群化消息服务解决方案项目概述架构图使用说明服务端通过API接口推送消息给客户端调用方式 请求参数返回参数 客户端推送消息连接websocket或发送消息 接收消息项目地址作者信息 集群化消息服务解决方案 项目概述 集群化消息服务解决方案是一种用于处理大量消息的高可用…...
python数据结构操作与可视化的应用
Python具有丰富的数据结构操作和可视化库,可以进行各种数据结构的创建、编辑和分析,并将结果可视化。以下是几个常见的Python数据结构操作和可视化的应用示例: 1. 列表(List)操作和可视化: - 创建列表&a…...
【基于轻量型架构的WEB开发】课程 作业4 AOP
一. 单选题(共7题,38.5分) 1 (单选题)下列选项中,用于通知/增强处理的是( )。 A. Joinpoint B. Pointcut C. Aspect D. Advice 正确答案:D 答案解析:在面向切面编程ÿ…...
跨境独立站新手,如何用DuoPlus云手机破局海外社媒引流?
独立站作为电商领域的一个重要组成部分,其发展在最近几年里确实令人瞩目,对于想要进入跨境赛道的新手卖家来说,手上握着有优势的货源,建立小型的DTC独立站确实会比入驻第三方平台具有更大的灵活性。本文将给跨境卖家们总结独立站和…...
【Android、IOS、Flutter、鸿蒙、ReactNative 】标题栏
Android 标题栏 参考 Android Studio版本 配置gradle镜像 阿里云 Android使用 android:theme 显示标题栏 添加依赖 dependencies {implementation("androidx.appcompat:appcompat:1.6.1")implementation("com.google.android.material:material:1.9.0")…...
信息安全工程师(83)Windows操作系统安全分析与防护
一、Windows操作系统安全分析 系统漏洞: Windows操作系统由于其复杂性和广泛使用,可能存在一些已知或未知的漏洞。这些漏洞可能会被黑客利用,进行恶意攻击。微软会定期发布系统更新和补丁,以修复这些漏洞,提高系统的安…...
QT Unknown module(s) in QT 以及maintenance tool的更详细用法(qt6.6.0)
不小心接了同事的委托,帮改一个qt的工程代码。然后出事了,那个proj是qt5.9版本的吧,搞到6.6版本的环境中各种问题。至少有3个是这样的: :-1: error: Unknown module(s) in QT: multimedia 直接百度,好像很简单&#x…...
如何在vscode中安装git详细新手教程
一、安装git后点击vscode中的设置 今天教大家如何在VScode中编写代码后提交到git仓库,如果我们不想切换到git的命令行窗口,可以在VScode中配置git,然后就可以很方便快捷的把代码提交到仓库中。 二、在输入框中输入 git.path ,再点…...
JVM垃圾回收详解二(重点)
死亡对象判断方法 堆中几乎放着所有的对象实例,对堆垃圾回收前的第一步就是要判断哪些对象已经死亡(即不能再被任何途径使用的对象)。 引用计数法 给对象中添加一个引用计数器: 每当有一个地方引用它,计数器就加 1…...
VLAN 高级技术实验
目录 一、实验背景 二、实验任务 三、实验步骤 四、实验总结 一、实验背景 假如你是公司的网络管理员,为了节省内网的IP地址空间,你决定在内网部署VLAN聚合,同时为了限制不同业务之间的访问,决定同时部署MUX VLAN。 二、实验…...
windowsC#-创建和引发异常
异常用于指示在运行程序时发生了错误。 此时将创建一个描述错误的异常对象,然后使用 throw 语句或表达式引发。 然后,运行时搜索最兼容的异常处理程序。 当存在下列一种或多种情况时,程序员应引发异常: 1. 方法无法完成其定义的…...
python爬虫案例——请求的网页源码被加密,解密方法全过程(19)
文章目录 1、任务目标2、网页分析3、代码编写1、任务目标 目标网站:https://jzsc.mohurd.gov.cn/data/company,该网站的网页源码被加密了,用于本文测验 要求:解密该网站的网页源码,请求网站并返回解密后的明文数据,网页内容如下: 2、网页分析 进入网站,打开开发者模式,…...
详解广告联盟
某种程度上,动荡的程度甚于以往。产业链中快速挤进了众多不曾有过的角色,产业逻辑被完全颠覆。巨大的变化在几年间迅速产生,源头是快速发展的互联网和科技。 这个行业走到了十字路口,身处其中的大多数人感到乐观,但同…...
Getting accurate time estimates from your tea(从您的团队获得准确的时间估计)
Hi again. 嗨了。 Ready to get back into it? 准备好重新开始了吗? Let’s go. Time estimation, 我们走吧。时间估计, effort estimation, 努力估计, and capacity planning are all helpful techniques for creating your project schedule. 容量规划都是创建项…...
攻防世界35-easyupload-CTFWeb
攻防世界35-easyupload-CTFWeb 通过各种上传发现,过滤了php后缀和内容中有php的文件 有这几种方式上传一句话木马 <script language"php">eval($_POST[1]);</script> <?php eval($_POST[cmd]);?> <? eval($_POST[cmd]);?>…...
在Mysql中,如何定位慢查询
参考回答:之前我们有个项目做压测的时候有的接口非常的慢,接口的响应时间超过了2秒以上,因为在MySOL中也提供了慢日志查询的功能,可以在MySOL的系统配置文件中开启这个慢日志的功能,并且也可以设置SOL执行超过多少时间…...
三国曹魏古城建设网站/云计算培训
格式化是很常见的数据恢复案例故障,如果被格式化的盘是有重要的数据,那么一定要注意马上停止往这个盘写入文件。然后用数据恢复软件扫描恢复里面的数据。具体的恢复方法可以看下文了解。工具/软件:流星数据恢复软件 步骤1:先百度…...
一个网站的制作特点/网络推广合作协议
原文:SQL SERVER分区具体例子详解在日常工作中,我们会遇到以下的情况,一个表每日数万级的增长,而查询的数据通常是在本月或今年,以前的数据偶尔会用到,但查询和插入的效率越来越慢,用数据库分区会有助于解决…...
劫持别人的网站做违法的事会怎么样/学网络运营需要多少钱
文 | 刘星文Unfold我最近非常喜欢的一款App,清爽简洁,优雅美观,设计很出色。可以用它来拼图,也可以拼视频,效果很出色,比如下面这样的效果。Storyluxe如果想做出一些炫酷的效果,比如下面这样的&…...
泉州推广优化公司/北京网站优化页面
1. Java 堆空间 **发生频率:**5颗星 造成原因 无法在 Java 堆中分配对象 吞吐量增加 应用程序无意中保存了对象引用,对象无法被 GC 回收 应用程序过度使用 finalizer。finalizer 对象不能被 GC 立刻回收。finalizer 由结束队列服务的守护线程调用&a…...
黑龙江省建设集团网站/网站推广营销运营方式
python 转换图片为base64 图片转为base64 原理很简单 基本上那种语言都可以做到 写本文的原因是:csdn中导入markdown文件时,图片导入失败或者不能导入的问题 解决办法是:把markdown中的所有图片转为base64即可1. // 转为base64 之后这样写即可展示出图片 ![image-name][ima…...
扬州做阿里巴巴的公司网站/关键词优化的方法有哪些
问题描述 相信大家都会遇到过这种情况: 进入下一页面,并且在下一页面执行某一动作,返回要刷新,没有执行某一动作,返回不刷新。也就是当前页面要实现按照需求刷新页面 实现思路 在当前页面定义个Bool类型属性 isNeedRef…...