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

一、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

四、注意事项

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。

你可能感兴趣的:(iOS学习,ios,swift)