当前位置: 首页 > news >正文

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(无主引用)两种解决方案。

  1. 弱引用(weak):适用于可能在生命周期中变为 nil 的对象。弱引用不会增加引用计数,因此当没有其他强引用时,对象会被释放。
  2. 无主引用(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 内存管理误区

  1. 过度使用强引用:所有对象都默认使用强引用,但在合适的地方应使用弱引用以避免循环引用。
  2. 滥用无主引用:无主引用适用于不会变为 nil 的对象,否则会导致崩溃。
  3. 闭包导致的循环引用:闭包中对 self 的隐式强引用是循环引用的常见原因,使用捕获列表可以避免此问题。

11.6 ARC 优化实践

  1. 分析引用关系:在设计类之间的引用关系时,避免循环引用的结构,适当地使用 weak 或 unowned 关键字。

  2. 善用工具:Xcode 提供了内存图和 Instruments 工具,可以帮助检测内存泄漏和循环引用。

  3. 定期释放对象:在可能产生强引用的地方(如闭包、异步操作等),确认对象在使用后被正确释放。

通过本章的学习,你掌握了 Swift 中的内存管理基础,包括 ARC 的工作原理、强引用和弱引用的使用、以及如何避免循环引用。合理的内存管理对提高应用性能和稳定性至关重要。下一章将介绍 Swift 的高级特性之一:协议和协议扩展,用于构建更具灵活性和扩展性的代码结构。

相关文章:

Swift 开发教程系列 - 第11章:内存管理和 ARC(Automatic Reference Counting)

在 Swift 中&#xff0c;内存管理由 ARC&#xff08;自动引用计数&#xff09;机制自动处理。ARC 通过追踪和管理对象的引用计数来确保分配的内存得到有效释放。尽管 ARC 在大多数情况下能够高效地管理内存&#xff0c;但理解其工作原理仍然十分重要&#xff0c;因为不当的引用…...

C#中 layout的用法

在C#中&#xff0c;layout并不是一个直接用于C#语言本身的关键字或特性。然而&#xff0c;layout在与C#紧密相关的某些上下文中确实有其用途&#xff0c;特别是在涉及用户界面&#xff08;UI&#xff09;设计和数据展示时。以下是几个常见的与layout相关的用法场景&#xff1a;…...

【编程概念基础知识】

、编程基础 一、面向对象的三大特性 1、封装&#xff1a; 盒子、零件、按钮 隐藏对象 的内部状态&#xff0c;并且只通过对象的方法来访问数据 想象你有一个小盒子&#xff08;这个盒子就是一个类&#xff09;&#xff0c;里面装着一些零件&#xff08;这些零件就是数据&a…...

【React】深入理解 JSX语法

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 深入理解 JSX语法1. JSX 简介2. JSX 的基本语法2.1 基本结构2.2 与普通 JavaScr…...

【Linux】从零开始使用多路转接IO --- 理解EPOLL的 LT水平触发模式 与 ET边缘触发模式

当你偶尔发现语言变得无力时&#xff0c; 不妨安静下来&#xff0c; 让沉默替你发声。 --- 里则林 --- 从零开始认识多路转接 1 EPOLL优缺点2 EPOLL工作模式 1 EPOLL优缺点 poll 的优点(和 select 的缺点对应) 接口使用方便&#xff1a;虽然拆分成了三个函数&#xff0c;…...

QtLua

描述 QtLua 库旨在使用 Lua 脚本语言使 Qt4/Qt5 应用程序可编写脚本。它是 QtScript 模块的替代品。 QtLua 不会为 Qt 生成或使用生成的绑定代码。相反&#xff0c;它提供了有用的 C 包装器类&#xff0c;使 C 和 lua 对象都可以从 lua 和 C 访问。它利用 Qt 元对象系统将 QOb…...

c++-有关计数、双变量累加、半衰、阶乘、变量值互换的基础知识

C是一种非常强大和灵活的编程语言&#xff0c;它包含了许多重要的概念和技巧。在本文中&#xff0c;我们将重点讨论五个主题&#xff1a;计数、双变量累加、半衰、阶乘和变量值的互换。我们将介绍这些概念的定义、用法、题目、答案和解释&#xff0c;以帮助读者更好地理解和运用…...

MyBatis3-获取参数值的方式、查询功能及特殊SQL执行

目录 准备工作 获取参数值的方式&#xff08;重点&#xff09; 查询功能 查询一个实体类对象 查询一个list集合 查询单个数据 查询一条数据为map集合 查询多条数据为map集合 特殊SQL执行 模糊查询 批量删除 动态设置表名 添加功能获取自增的主键 准备工作 模块My…...

web——[SUCTF 2019]EasySQL1——堆叠注入

这个题主要是讲述了堆叠注入的用法&#xff0c;来复现一下 什么是堆叠注入 堆叠注入&#xff1a;将多条SQL语句放在一起&#xff0c;并用分号;隔开。 1.查看数据库的名称 查看数据库名称 1;show databases; 发现有名称为ctftraining的数据库 2.对表进行查询 1;show tabl…...

【Ubuntu学习】Ubuntu无法使用vim命令编辑

问题 在VMware首次安装Ubuntu&#xff0c;使用vi指令对文件进行编辑&#xff0c;按i键后无法更改文件内容。 原因 由于Ubuntu中预装的是vim-tiny&#xff0c;平时开发中需要使用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. 引言 在现代操作系统中&#xff0c;信号是一种进程间通信机制&#xff0c;它允许操作系统或其他进程向一个进程发送消息。信号可以用来通知进程发生了一些重要事件&#xff0c;如用户请求终止进程、硬件异常、定时器超时等。掌握信号处理技术对于开发健壮、高效的系统程序至…...

什么是工单管理系统?全面认识指南

在现代企业中&#xff0c;客户服务和支持是业务成功的关键因素之一。为了有效地管理客户请求和问题&#xff0c;许多公司采用了工单管理系统。本文将深入探讨工单管理系统的定义、功能、优势。 一、工单管理系统的定义 工单管理系统是一种软件工具&#xff0c;旨在帮助企业管…...

集群化消息服务解决方案

目录 集群化消息服务解决方案项目概述架构图使用说明服务端通过API接口推送消息给客户端调用方式 请求参数返回参数 客户端推送消息连接websocket或发送消息 接收消息项目地址作者信息 集群化消息服务解决方案 项目概述 集群化消息服务解决方案是一种用于处理大量消息的高可用…...

python数据结构操作与可视化的应用

Python具有丰富的数据结构操作和可视化库&#xff0c;可以进行各种数据结构的创建、编辑和分析&#xff0c;并将结果可视化。以下是几个常见的Python数据结构操作和可视化的应用示例&#xff1a; 1. 列表&#xff08;List&#xff09;操作和可视化&#xff1a; - 创建列表&a…...

【基于轻量型架构的WEB开发】课程 作业4 AOP

一. 单选题&#xff08;共7题&#xff0c;38.5分&#xff09; 1 (单选题)下列选项中&#xff0c;用于通知/增强处理的是&#xff08; &#xff09;。 A. Joinpoint B. Pointcut C. Aspect D. Advice 正确答案&#xff1a;D 答案解析&#xff1a;在面向切面编程&#xff…...

跨境独立站新手,如何用DuoPlus云手机破局海外社媒引流?

独立站作为电商领域的一个重要组成部分&#xff0c;其发展在最近几年里确实令人瞩目&#xff0c;对于想要进入跨境赛道的新手卖家来说&#xff0c;手上握着有优势的货源&#xff0c;建立小型的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操作系统安全分析 系统漏洞&#xff1a; Windows操作系统由于其复杂性和广泛使用&#xff0c;可能存在一些已知或未知的漏洞。这些漏洞可能会被黑客利用&#xff0c;进行恶意攻击。微软会定期发布系统更新和补丁&#xff0c;以修复这些漏洞&#xff0c;提高系统的安…...

QT Unknown module(s) in QT 以及maintenance tool的更详细用法(qt6.6.0)

不小心接了同事的委托&#xff0c;帮改一个qt的工程代码。然后出事了&#xff0c;那个proj是qt5.9版本的吧&#xff0c;搞到6.6版本的环境中各种问题。至少有3个是这样的&#xff1a; :-1: error: Unknown module(s) in QT: multimedia 直接百度&#xff0c;好像很简单&#x…...

如何在vscode中安装git详细新手教程

一、安装git后点击vscode中的设置 今天教大家如何在VScode中编写代码后提交到git仓库&#xff0c;如果我们不想切换到git的命令行窗口&#xff0c;可以在VScode中配置git&#xff0c;然后就可以很方便快捷的把代码提交到仓库中。 二、在输入框中输入 git.path &#xff0c;再点…...

JVM垃圾回收详解二(重点)

死亡对象判断方法 堆中几乎放着所有的对象实例&#xff0c;对堆垃圾回收前的第一步就是要判断哪些对象已经死亡&#xff08;即不能再被任何途径使用的对象&#xff09;。 引用计数法 给对象中添加一个引用计数器&#xff1a; 每当有一个地方引用它&#xff0c;计数器就加 1…...

VLAN 高级技术实验

目录 一、实验背景 二、实验任务 三、实验步骤 四、实验总结 一、实验背景 假如你是公司的网络管理员&#xff0c;为了节省内网的IP地址空间&#xff0c;你决定在内网部署VLAN聚合&#xff0c;同时为了限制不同业务之间的访问&#xff0c;决定同时部署MUX VLAN。 二、实验…...

windowsC#-创建和引发异常

异常用于指示在运行程序时发生了错误。 此时将创建一个描述错误的异常对象&#xff0c;然后使用 throw 语句或表达式引发。 然后&#xff0c;运行时搜索最兼容的异常处理程序。 当存在下列一种或多种情况时&#xff0c;程序员应引发异常&#xff1a; 1. 方法无法完成其定义的…...

python爬虫案例——请求的网页源码被加密,解密方法全过程(19)

文章目录 1、任务目标2、网页分析3、代码编写1、任务目标 目标网站:https://jzsc.mohurd.gov.cn/data/company,该网站的网页源码被加密了,用于本文测验 要求:解密该网站的网页源码,请求网站并返回解密后的明文数据,网页内容如下: 2、网页分析 进入网站,打开开发者模式,…...

详解广告联盟

某种程度上&#xff0c;动荡的程度甚于以往。产业链中快速挤进了众多不曾有过的角色&#xff0c;产业逻辑被完全颠覆。巨大的变化在几年间迅速产生&#xff0c;源头是快速发展的互联网和科技。 这个行业走到了十字路口&#xff0c;身处其中的大多数人感到乐观&#xff0c;但同…...

Getting accurate time estimates from your tea(从您的团队获得准确的时间估计)

Hi again. 嗨了。 Ready to get back into it? 准备好重新开始了吗&#xff1f; 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 通过各种上传发现&#xff0c;过滤了php后缀和内容中有php的文件 有这几种方式上传一句话木马 <script language"php">eval($_POST[1]);</script> <?php eval($_POST[cmd]);?> <? eval($_POST[cmd]);?>…...

在Mysql中,如何定位慢查询

参考回答&#xff1a;之前我们有个项目做压测的时候有的接口非常的慢&#xff0c;接口的响应时间超过了2秒以上&#xff0c;因为在MySOL中也提供了慢日志查询的功能&#xff0c;可以在MySOL的系统配置文件中开启这个慢日志的功能&#xff0c;并且也可以设置SOL执行超过多少时间…...

三国曹魏古城建设网站/云计算培训

格式化是很常见的数据恢复案例故障&#xff0c;如果被格式化的盘是有重要的数据&#xff0c;那么一定要注意马上停止往这个盘写入文件。然后用数据恢复软件扫描恢复里面的数据。具体的恢复方法可以看下文了解。工具/软件&#xff1a;流星数据恢复软件 步骤1&#xff1a;先百度…...

一个网站的制作特点/网络推广合作协议

原文:SQL SERVER分区具体例子详解在日常工作中&#xff0c;我们会遇到以下的情况&#xff0c;一个表每日数万级的增长&#xff0c;而查询的数据通常是在本月或今年&#xff0c;以前的数据偶尔会用到&#xff0c;但查询和插入的效率越来越慢&#xff0c;用数据库分区会有助于解决…...

劫持别人的网站做违法的事会怎么样/学网络运营需要多少钱

文 | 刘星文Unfold我最近非常喜欢的一款App&#xff0c;清爽简洁&#xff0c;优雅美观&#xff0c;设计很出色。可以用它来拼图&#xff0c;也可以拼视频&#xff0c;效果很出色&#xff0c;比如下面这样的效果。Storyluxe如果想做出一些炫酷的效果&#xff0c;比如下面这样的&…...

泉州推广优化公司/北京网站优化页面

1. Java 堆空间 **发生频率&#xff1a;**5颗星 造成原因 无法在 Java 堆中分配对象 吞吐量增加 应用程序无意中保存了对象引用&#xff0c;对象无法被 GC 回收 应用程序过度使用 finalizer。finalizer 对象不能被 GC 立刻回收。finalizer 由结束队列服务的守护线程调用&a…...

黑龙江省建设集团网站/网站推广营销运营方式

python 转换图片为base64 图片转为base64 原理很简单 基本上那种语言都可以做到 写本文的原因是:csdn中导入markdown文件时,图片导入失败或者不能导入的问题 解决办法是:把markdown中的所有图片转为base64即可1. // 转为base64 之后这样写即可展示出图片 ![image-name][ima…...

扬州做阿里巴巴的公司网站/关键词优化的方法有哪些

问题描述 相信大家都会遇到过这种情况&#xff1a; 进入下一页面&#xff0c;并且在下一页面执行某一动作&#xff0c;返回要刷新&#xff0c;没有执行某一动作&#xff0c;返回不刷新。也就是当前页面要实现按照需求刷新页面 实现思路 在当前页面定义个Bool类型属性 isNeedRef…...