NSKeyValueObservation:无法从对象中删除键路径的观察者,因为它没有注册为观察者 [英] NSKeyValueObservation: Cannot remove an observer for the key path from object because it is not registered as an observer

查看:433
本文介绍了NSKeyValueObservation:无法从对象中删除键路径的观察者,因为它没有注册为观察者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用中出现随机崩溃(无法在我拥有的设备上重现),但例外:

I get random crashes (which I can't reproduce on devices I own) in my app with exception:

由于未注册为观察者,因此无法从AVPlayerLayer 0xaddress中删除键路径"readyForDisplay"的观察者Foundation.NSKeyValueObservation 0x地址.

Cannot remove an observer Foundation.NSKeyValueObservation 0xaddress for the key path "readyForDisplay" from AVPlayerLayer 0xaddress because it is not registered as an observer.

当我取消分配包含AVPlayerLayer的UIView时会发生这种情况.

This happens when I deallocate a UIView which contains AVPlayerLayer.

我的初始化:

private var playerLayer : AVPlayerLayer { return self.layer as! AVPlayerLayer }

init(withURL url : URL) {
    ...
    self.asset = AVURLAsset(url: url)
    self.playerItem = AVPlayerItem(asset: self.asset)
    self.avPlayer = AVPlayer(playerItem: self.playerItem)
    super.init(frame: .zero)
    ...
    let avPlayerLayerIsReadyForDisplayObs = self.playerLayer.observe(\AVPlayerLayer.isReadyForDisplay, options: [.new]) { [weak self] (plLayer, change) in ... }
    self.kvoPlayerObservers = [..., avPlayerLayerIsReadyForDisplayObs, ...]
    ...
    }

我的引发异常的deinit:

My deinit where exception is thrown:

deinit {
    self.kvoPlayerObservers.forEach { $0.invalidate() }
    ...
    NotificationCenter.default.removeObserver(self)
}

根据Crashlytics,它发生在不同iPhone上的iOS 11.4.1上.

According to Crashlytics it happens on iOS 11.4.1 on different iPhones.

导致deinit的代码非常简单:

// Some UIViewController context.
self.viewWithAVLayer?.removeFromSuperview()
self.viewWithAVLayer = nil

对于为什么会发生这种情况,我将不胜感激.

I would appreciate any thoughts on why this happens.

我已经看到此错误,但这似乎不是原因对我来说.

I have seen this bug but it doesn't seem to be the cause for me.

后代的其他信息.在iOS 10上,如果我不使我无效,则会在deinit上出现可重现的崩溃.在iOS 11上,它可以在没有失效的情况下正常工作(如果我不失效并让观察者与我的班级一起被观察者使用,是否崩溃是否消失还没有检查).

Additional info for posterity. On iOS 10 if I don't invalidate I get reproducible crash on deinit. On iOS 11 it works without invalidation (not checked yet if crash disappears if I don't invalidate and let observers to be deinited with my class).

后代的其他信息:我还发现了这个可能与以下Swift错误有关的错误- SR- 6795 .

Additional info for posterity: I have also found this Swift bug which might be related - SR-6795.

推荐答案

之后

self.kvoPlayerObservers.forEach { $0.invalidate() }

添加

self.kvoPlayerObservers.removeAll()

我也不喜欢这一行:

self.kvoPlayerObservers = [..., avPlayerLayerIsReadyForDisplayObs, ...]

kvoPlayerObservers应该是一个Set,接收观察者时,应一个接一个地插入它们.

kvoPlayerObservers should be a Set and you should insert observers one by one as you receive them.

这篇关于NSKeyValueObservation:无法从对象中删除键路径的观察者,因为它没有注册为观察者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆