【发布时间】:2017-12-08 19:32:28
【问题描述】:
大家都知道,在 iOS 中使用 Firebase 的强大功能时,
每当您在视图控制器中进行观察时,
var o: DatabaseReference?
var o2: DatabaseReference?
var o3: DatabaseReference?
当屏幕消失时,您必须终止所有观察...
private func clearObservations() {
print("\n\n clearing observations! \n\n")
if o != nil {
o?.removeAllObservers()
o = nil
}
if o2 != nil {
etc...
}
但是!
经过大量测试,您不能在deinit 中调用clearObservations() - 您必须在viewDidDisappear(或其他合乎逻辑的位置)中调用它。
再次 - 它在 deinit 中明确不起作用。
我的问题,为什么实际上这在deinit 中不起作用?
顺便说一句,您可以像这样启动 Firebase 观察者:
say, viewWillAppear#
o = Database.database().reference(withPath: "string")
o!.observe(.value, with: { (snapshot) in
self.blah(snapshot)
})
【问题讨论】:
-
不确定这只是一个猜测,但在调用 deinit 时,内存已被释放,因此在其中调用某些内容将不起作用,因为不再指向内存。或者正如 Rob 提到的如果没有调用 deinit 本身,则检查保留周期。
-
为什么说“不能在
deinit中调用clearObservers()”?是它崩溃了还是因为没有调用deinit?标准观察者在deinit中被删除。 (或者新的 Swift 4 观察者模式完全消除了这个问题。)如果是deinit没有被调用,那么你的 Firebase 观察者中可能有一些东西(涉及到任何闭包?)导致强引用循环,而不是依赖于viewDidDisappear模式,也许你应该只修复根强引用循环问题。也许向我们展示您是如何创建这些 Firebase 观察者之一的。 -
嗨@Rob:我们对其进行了测试(非常广泛,在大量设备/操作系统上),它实际上并没有清除 Firebase 观察者,他们继续观察云端的地狱(有没有崩溃)
-
仅供参考“在 deinit 中删除了标准观察者”,这真的很有趣;不知道 - 请注意,Firebase“观察者”与 Swift 观察者绝对没有任何联系,这只是命名的巧合。 :O
-
@Fattie - 所以问题是你的
deinit是否被调用。我打赌不是,很可能是因为你的闭包没有使用[weak self]或[unowned self]模式。由于这些闭包,我猜测一个简单的强引用循环,并且假设所有这些都是真的(我只是猜测你没有分享如何添加观察者的示例),最好消除这些强参考周期,而不是围绕它们进行编程。