ARC(自动引用计数)是一种在 Swift 中的自动内存管理系统。每当一个新强引用指向对象时,计数器增加;删除时减少。当计数器为零时,对象被释放。
保留循环(retain cycle)是指对象之间相互引用强引用,导致它们永远不会被释放的情况。
避免的方法:
protocol SomeDelegate: AnyObject { } class Owner { weak var delegate: SomeDelegate? }
[weak self] 或 [unowned self]:class Example { var closure: (() -> Void)? func setup() { closure = { [weak self] in self?.doSomething() } } func doSomething() { } }
[weak self] 和 [unowned self] 在闭包中有什么区别?在什么情况下使用哪个类型的引用?
答案:
[weak self] 创建一个可选引用;self 可能为 nil,因此通常使用安全解包 self?。[unowned self] 创建一个非可选引用,并且不会增加计数器;如果对象已经被释放并且发生了访问 — 将崩溃。[unowned self]。示例:
someClosure = { [weak self] in self?.doTask() } // 或(如果 self 100% 比闭包存活得久): someClosure = { [unowned self] in doTask() }
故事
在项目中,ViewController 和它的处理点击的闭包之间出现了保留循环。ViewController 引用闭包,该闭包以强引用捕获了 self。结果是,控制器和它的所有数据在关闭屏幕后没有被释放。通过在闭包中引入 [weak self] 解决了这个问题。
故事
在两个对象之间实现委托模式。委托被声明为强(
strong)属性。结果在尝试从内存中删除主对象时,它没有被释放,导致内存泄漏。将委托转换为 weak 后,问题消失了。
故事
为动画使用了 UIView 中的闭包。闭包通过
[unowned self]捕获 self。当在动画完成之前删除视图时,由于访问已释放的 self,应用崩溃。解决方案是使用[weak self]并在闭包中强制检查 self 是否为 nil。