问题描述
我的应用中出现随机崩溃(无法在我拥有的设备上重现),但例外:
I get random crashes (which I can't reproduce on devices I own) in my app with exception:
当我取消分配包含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 deinit
ed 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:无法从对象中删除键路径的观察者,因为它没有注册为观察者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!