我的应用程序中出现随机崩溃(我无法在我拥有的设备上重现),但有例外:
无法从 AVPlayerLayer 0xaddress 中删除关键路径“readyForDisplay”的观察者 Foundation.NSKeyValueObservation 0xaddress,因为它未注册为观察者。
当我释放包含 AVPlayerLayer 的 UIView 时会发生这种情况。
My init:
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 抛出异常:
deinit {
self.kvoPlayerObservers.forEach { $0.invalidate() }
...
NotificationCenter.default.removeObserver(self)
}
据 Crashlytics 称,不同 iPhone 上的 iOS 11.4.1 上都会出现这种情况。
代码导致deinit
很简单:
// Some UIViewController context.
self.viewWithAVLayer?.removeFromSuperview()
self.viewWithAVLayer = nil
如果有任何关于为什么会发生这种情况的想法,我将不胜感激。
我见过this bug https://bugs.swift.org/browse/SR-5816但这似乎不是我的原因。
EDIT 1:
供后代使用的附加信息。在 iOS 10 上,如果我不使失效,我会在 deinit 时出现可重现的崩溃。在 iOS 11 上,它可以在没有失效的情况下工作(如果我不失效并让观察者成为,则崩溃是否消失,尚未检查)deinit
与我的班级一起编辑)。
EDIT 2:
给后代的附加信息:我还发现了这个可能相关的 Swift bug -SR-6795 https://bugs.swift.org/browse/SR-6795.