当前位置: 首页 > 工具软件 > Flying-Swift > 使用案例 >

Swift中易导致泄露的注意事项

况喜
2023-12-01

一、ARC 自动引用计数

Swift 使用自动引用计数 (ARC) 来跟踪并管理应用使用的内存。大部分情况下,这意味着在 Swift 语言中,内存管理自动完成,不需要自己去考虑内存管理的事情。当实例不再被使用时,ARC会自动释放这些类的实例所占用的内存。

每一个实例有引用数,每次有别的实例引用它时,引用数加一。每一次引用该实例的实例销毁时,引用数减一。等引用数等于0时,该实例被销毁。


二、循环引用

class MyViewController: UIViewController {
    var view = MyView()     
    view.delegate = self   
}

protocol MyViewDelegate: NSObject {

}

class MyView: UIView {
    var delegate: MyViewDelegate?
}

上述代码会引起循环引用,因为 vc 引用了 view,view 引用了 vc,两者的引用数永远不会为0,该实例不会被销毁,引起内存泄露。


三、解决方案

修改上述代码如下:

class MyView: UIView {

    weak var delegate: MyViewDelegate?
}

引起循环引用的根本原因就是相互引用导致引用数各自加 1,解决办法则是把 强引用( 增加引用数 ) 改为 弱引用( 不增加引用数 )。根据实际情况,一般把 被动 及 子实例 设为对 父实例 弱引用。
设置 Delegate 的基本原则所有的 Delegate 应该设为 weak

四、注意事项

  1. weak 修饰 delegate
protocol ProtocolOne {
  func run() -> Void
}

protocol ProtocolTwo : class {
  func run() -> Void
}

class MyView {
  weak var delegate: ProtocolOne? // 会提示错误 ‘weak’ cannot be applied to non-class type
  weak var delegate: ProtocolTwo?
}

由于 Swift 中任何元素都可以遵循协议,但是非 class 类不能使用 weak。 所以需要设置为 delegate 的协议需要遵循 class 协议,来声明自己是 class-only-protocol,否则没法设置 weak。

  1. CABasicAnimation 中的 delegate
/* The delegate of the animation. This object is retained for the
     * lifetime of the animation object. Defaults to nil. See below for the
     * supported delegate methods. */
    
    open var delegate: CAAnimationDelegate?

如上源码:在CAAnimation中,其代理delegate是被强持有的,并没有加weak修饰,所以在使用后一定要找时机将delegate释放掉,不然会造成内存泄漏。
释放时机可以是 animationDidStop 之后。

 类似资料: