【问题标题】:Swift KVO holding object reference countSwift KVO 持有对象引用计数
【发布时间】:2020-06-12 19:42:38
【问题描述】:

我在我的 swift 代码中添加观察者如下:

private var keyValueObservations = [NSKeyValueObservation]()

然后在代码中

  let keyValueObservation = session.observe(\.isRunning, options: .new) { _, change in
          guard let isSessionRunning = change.newValue else { return }

          DispatchQueue.main.async {[weak self] in
            //  self.recordButton.isEnabled = isSessionRunning
            self?.delegate?.cameraSessionStartedRunning(session: self?.session)
          }
      }
      keyValueObservations.append(keyValueObservation)

然后

 private func removeObservers() {
      for keyValueObservation in keyValueObservations {
          keyValueObservation.invalidate()
      }

      keyValueObservations.removeAll()
  }


 deinit {
      removeObservers()
      NSLog("Calling deinit on \(type(of: self))")
  }

问题是这似乎保留了 self 的引用计数,因此无法通过将其设置为 nil 来释放对象。结果永远不会调用 Deinit。我该如何解决?

【问题讨论】:

  • @matt 这来自 Apple 提供的示例代码。虽然不能保证它是安全的。
  • @Rob 我认为你是对的,另一行导致了这个问题,尽管它看起来与我发布的代码非常相似。现在可能出了什么问题?
  • 我现在更新了代码行,请看一下

标签: ios swift swift4 key-value-observing


【解决方案1】:

这里的问题是你比你想象的更早地捕捉到自我。这应该可以解决它:

let keyValueObservation = session.observe(\.isRunning, options: .new) { [weak self] _, change in
    guard let isSessionRunning = change.newValue else { return }

    DispatchQueue.main.async { [weak self] in
        //  self.recordButton.isEnabled = isSessionRunning
        self?.delegate?.cameraSessionStartedRunning(session: self?.session)
    }
}
keyValueObservations.append(keyValueObservation)

所以你看到是观察者函数的闭包在分派回主线程时捕获自我而不是。

【讨论】:

  • 我想通了,但想知道为什么之前没有对 self 的引用时 self 被更早地捕获?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-16
  • 2016-08-02
  • 2016-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多