Swift内存管理完全指南:ARC、弱引用与循环引用破解(Swift编程语言中文版)
Swift内存管理完全指南ARC、弱引用与循环引用破解Swift编程语言中文版【免费下载链接】the-swift-programming-language-in-chinese中文版 Apple 官方《Swift 编程语言》项目地址: https://gitcode.com/gh_mirrors/th/the-swift-programming-language-in-chineseSwift 内存管理靠 ARC自动引用计数自动追踪对象引用次数并释放内存。本指南基于官方《Swift 编程语言》中文版用最少的代码带你看懂什么是强引用循环、如何用 weak 弱引用与 unowned 无主引用破解循环引用以及如何用闭包捕获列表解决闭包循环引用帮你彻底告别 Swift 内存泄漏。一、ARC 是什么Swift 如何自动管理内存在 Swift 中你几乎不需要手动释放内存。每次创建一个类class实例ARC 都会分配内存并记录当前有多少变量引用它——这就是引用计数。只要至少存在一个强引用对象就不会被释放当引用计数归零时ARC 自动回收内存。理解 ARC 之前先分清两种类型这决定了谁需要 ARC 管理结构体struct是值类型赋值时整体复制各改各的互不影响天然不会互相引用也就不存在循环引用问题。类class是引用类型赋值时只复制指向多个变量可共享同一个实例这正是内存管理的核心场景。 一句话记忆ARC 只管理类的实例结构体和枚举是值类型不参与引用计数。想确认对象何时被释放可以给类加一个deinit析构器打印日志详见 Deinitialization.md。二、最大的坑强引用循环新手最常见的内存泄漏是两个类实例互相持有强引用导致引用计数永远到不了零。看官方文档里的经典例子 Person类有一个apartment属性Apartment类有一个tenant属性它们这样互相指向——john!.apartment unit4A unit4A!.tenant john // 循环引用诞生此时即使把外部变量john和unit4A都设为nil两个实例仍被彼此拽在内存里析构器永远不会执行——这就是内存泄漏。三、解法一弱引用weak打破循环弱引用是一种不占引用计数的引用。在属性前加weak关键字即可weak var tenant: Person?弱引用有两个关键特性不阻止对象释放——对象被释放后弱引用会被 ARC 自动置为nil必须是可选变量weak var x: T?因为它的值可能随时变成nil。适用场景对方生命周期可能比自己短、可能不存在的关系例如公寓可能有租户也可能空置。四、解法二无主引用unowned打破循环无主引用同样不增加引用计数写法是加unowned关键字unowned let customer: Customer官方例子是Customer和CreditCard一张信用卡必然属于某个客户不可能为空但客户不一定持有卡。因此卡的customer属性声明为无主引用客户的card属性保持强引用。⚠️重要区别无主引用不是可选类型ARC 也永远不会把它置为nil。一旦你访问一个已释放对象的无主引用程序会直接崩溃。所以只在目标对象一定先于自己存在时才用。对比项weak 弱引用unowned 无主引用增加引用计数❌ 不增加❌ 不增加是否可选类型✅ 必须可选❌ 非可选对象释放后自动变为nil安全访问会崩溃适用关系对方可能有对方一定有五、闭包循环引用self背后的隐形泄漏闭包也是引用类型。如果闭包被存为类的属性而闭包内部又访问了self就会捕获 self形成类实例 ↔ 闭包的循环引用——这是回调、事件处理器、定时器场景中最常见的泄漏。破解方法是闭包捕获列表——在闭包开头显式声明如何捕获 selflazy var asHTML: () - String { [unowned self] in // 或 [weak self] in // ...闭包体 }[unowned self]闭包和对象必定同时生灭时如本例的asHTML使用无需解包性能更好[weak self]闭包可能比对象存活得更久时使用闭包体内需guard let self else { return }解包。 关于闭包值捕获的更多细节可阅读 Closures.md。六、实践速查表怎么选、怎么验证场景该用哪个关键字父对象持有子对象子可能有父的引用父→子用强引用子→父用weak子对象必定跟随父对象生灭如卡必属于客户父→子强引用子→父unowned闭包属性访问self闭包与对象同生同死捕获列表[unowned self]网络回调、Timer 等闭包可能活得比对象久捕获列表[weak self]✅三步验证法给类加deinit { print(释放了) }运行看日志——没打印就是泄漏用 Xcode 内存图工具检查对象引用关系记住口诀循环里至少留一条不计数的边weak 或 unowned。另外两个易踩的坑弱引用被 ARC 自动置nil时不会触发didSet属性观察器无主可选引用unowned var x: T?可用于链表式结构如课程的下一门课但需自行保证指向有效对象。七、延伸阅读官方中文文档导航本项目是 Apple 官方《The Swift Programming Language》的完整中文翻译以下章节与本文主题直接相关建议配合阅读 TSPL.docc/LanguageGuide/AutomaticReferenceCounting.md —— ARC 核心章节含全部图示示例 TSPL.docc/LanguageGuide/ClassesAndStructures.md —— 值类型与引用类型的差异 TSPL.docc/LanguageGuide/Deinitialization.md —— 析构器与资源清理 TSPL.docc/LanguageGuide/Closures.md —— 闭包与值捕获 TSPL.docc/LanguageGuide/MemorySafety.md —— 内存安全与访问冲突 全书入口TSPL.docc/The-Swift-Programming-Language.md掌握 ARC、weak 弱引用、unowned 无主引用与闭包捕获列表这四把钥匙你就掌握了 Swift 内存管理的全部核心可以自信地写出零泄漏的 Swift 应用了 【免费下载链接】the-swift-programming-language-in-chinese中文版 Apple 官方《Swift 编程语言》项目地址: https://gitcode.com/gh_mirrors/th/the-swift-programming-language-in-chinese创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考