在 Swift 的内存管理机制中,weak 与 unowned 引用在语义和行为上存在哪些关键差异?请说明在何种具体场景下应优先选用其中一种,并解释理由。
考察说明
考查对 Swift 自动引用计数(ARC)中弱引用和无主引用语义差异的理解,以及在实际内存管理场景中的选型判断能力。
回答思路
- 【回答框架 1】weak 引用不会增加对象的引用计数,当被引用的对象被释放后,weak 引用会被自动置为 nil,因此 weak 引用必须是可选类型。它通常用于可能存在循环引用且一方可能先被释放的场景,例如 delegate 属性。
- 【回答框架 2】unowned 引用同样不增加引用计数,但不被自动置为 nil,它假定被引用的对象生命周期与自身相同或更长。使用 unowned 必须确保被引用对象不会提前释放,否则访问已释放的内存会导致运行时崩溃。
- 【回答框架 3】选择依据主要看生命周期关系:如果被引用对象可能先于当前对象释放,应使用 weak;如果可以保证被引用对象与当前对象生命周期一致或更长,可以使用 unowned。例如闭包捕获 self 时,若闭包与 self 生命周期绑定可考虑 unowned,否则用 weak 更安全。
- 【关键点 1】weak 引用是可选类型,对象释放后自动置 nil。
- 【关键点 2】unowned 非可选,对象释放后访问会崩溃。
- 【关键点 3】无法确定生命周期时优先 weak,unowned 需明确保证不提前释放。
- 【易错点 1】将 unowned 用于可能先释放的对象,导致悬垂指针崩溃。
- 【易错点 2】weak 引用不增加计数,但不能用于强制持有对象。
- 【易错点 3】在闭包捕获中误用 unowned,忽略 self 可能为 nil 的场景。