返回

RxSwift:探索 dealloc

IOS

在 RxSwift 中,deinit 等价于 dealloc,当订阅上述两个序列时,deinit 被调用时,上述两个序列将触发信号发送。执行顺序为:deallocating -> deinit -> deallocated。让我们看一段代码:

let disposeBag = DisposeBag()

// 订阅序列 1
_ = observable1.subscribe(onNext: { _ in
  print("序列 1 收到元素")
}, onCompleted: {
  print("序列 1 完成")
})
.disposed(by: disposeBag)

// 订阅序列 2
_ = observable2.subscribe(onNext: { _ in
  print("序列 2 收到元素")
}, onCompleted: {
  print("序列 2 完成")
})
.disposed(by: disposeBag)

// 调用 `deinit`
disposeBag.invalidate()

在这段代码中,我们订阅了两个序列 (observable1observable2),并在 disposeBag 被销毁时将它们释放。当 disposeBag 被销毁时,deinit 将被调用,并触发 observable1observable2 发送完成信号。

以下是一些关键点:

  • deinit 是在对象从内存中释放时调用的。 在 RxSwift 中,deinit 等效于 dealloc
  • 当订阅的序列释放时,deinit 会被触发。 这是因为序列被存储在 DisposeBag 中,而 DisposeBag 在销毁时会调用 deinit
  • deinit 的执行顺序是:deallocating -> deinit -> deallocated

避免内存泄漏

如果不正确地处理 deinit,可能会导致内存泄漏。例如,以下代码会导致内存泄漏:

class MyClass {
  // 订阅序列
  private let subscription = observable.subscribe()
}

在这个类中,序列的订阅没有被释放,当该类的实例从内存中释放时,序列将继续存在并保持对对象的强引用。这将导致内存泄漏,因为对象无法被垃圾回收。

为了避免这种情况,必须在 deinit 中释放序列的订阅。这可以通过以下方式完成:

class MyClass {
  // 订阅序列
  private var subscription: Disposable?

  deinit {
    // 释放序列订阅
    subscription?.dispose()
  }
}

通过在 deinit 中释放订阅,我们可以确保序列在对象从内存中释放时被释放,从而避免内存泄漏。

结论

了解 RxSwift 中的 deinit 非常重要,因为它有助于避免内存泄漏并确保资源在不再需要时被释放。通过正确地处理 deinit,可以编写健壮且高效的 RxSwift 代码。