AVPlayer 移除 Swift 2.2 中的观察者崩溃
AVPlayer removing observer crash in Swift 2.2
我有一个视频应用程序是我在 Swift 1 中构建的,我一直在尝试迁移到 Swift 2.2。除了与观察者有关的奇怪崩溃之外,这一切(最终)都有效。
func removeObservers()
{
print("REMOVING OBSERVERS")
if ( !self.is_image && self.player != nil ) {
if (self.player?.observationInfo != nil) {
self.player?.removeObserver(self, forKeyPath: "currentItem.status")
self.player?.removeObserver(self, forKeyPath: "readyForDisplay")
}
}
NSNotificationCenter.defaultCenter().removeObserver(self)
}
这在以前使用 SwiftTryCatch 时有效,但在“'Cannot remove an observer for the key path "readyForDisplay" from because it is not registered as an observer.'”的地方崩溃了,或者如果我将其注释掉,观察者会在已释放的对象上注册。
如果我添加一个 do { } catch {} 到它我得到一个错误 "this does not throw" 并且它同样崩溃。我如何着手将其放入某种形式的 try-catch 格式?
既然你是在方法的最后调用 removeObserver(self)
,为什么你不能取消上面代码的注释?因为 removeObserver(self)
会删除所有已注册的观察者。我希望这能解决您的问题。
NSNotificationCenter.defaultCenter().removeObserver(self)
在 Swift 2 中,库对真正意外的错误(抛出)与程序员本可以避免的错误(不扔,但只是让你的应用程序崩溃)。
(我不喜欢这种区别,或者至少不喜欢 Apple 做出的关于哪些错误属于哪个类别的所有具体决定。JSON API 接近荒谬在这个部门。但是……我们使用的是 API。)
NSKeyValueObserving
文档说:
It is an error to call removeObserver:forKeyPath:
if the object has not been registered as an observer.
“这是一个错误”是 Apple 代码,表示“您有责任永远不要这样做,如果您这样做,您的应用程序将以无法捕捉的方式崩溃。”
在这些情况下,通常可以调用 API 来检查您将要做的事情的有效性。但是,据我所知,您无法通过 KVO API 调用来询问“X 是否正在观察对象 Z 的关键路径 Y?”这意味着您有三个选择:
- 弄清楚你为什么试图从你没有观察到的东西中移除一个观察者,并使用你的程序自己的内部逻辑来阻止它。
- 为“我正在观察的玩家”保留一个弱实例变量,并在尝试移除观察者之前检查它是否匹配。
- 在删除之前将自己添加为观察者。 (我很确定冗余添加是可以的。)
status
是 AVPlayer
或 AVPlayerItem
的 属性。
readyForDisplay
是 AVPlayerLayer
的 属性
我有一个视频应用程序是我在 Swift 1 中构建的,我一直在尝试迁移到 Swift 2.2。除了与观察者有关的奇怪崩溃之外,这一切(最终)都有效。
func removeObservers()
{
print("REMOVING OBSERVERS")
if ( !self.is_image && self.player != nil ) {
if (self.player?.observationInfo != nil) {
self.player?.removeObserver(self, forKeyPath: "currentItem.status")
self.player?.removeObserver(self, forKeyPath: "readyForDisplay")
}
}
NSNotificationCenter.defaultCenter().removeObserver(self)
}
这在以前使用 SwiftTryCatch 时有效,但在“'Cannot remove an observer for the key path "readyForDisplay" from because it is not registered as an observer.'”的地方崩溃了,或者如果我将其注释掉,观察者会在已释放的对象上注册。
如果我添加一个 do { } catch {} 到它我得到一个错误 "this does not throw" 并且它同样崩溃。我如何着手将其放入某种形式的 try-catch 格式?
既然你是在方法的最后调用 removeObserver(self)
,为什么你不能取消上面代码的注释?因为 removeObserver(self)
会删除所有已注册的观察者。我希望这能解决您的问题。
NSNotificationCenter.defaultCenter().removeObserver(self)
在 Swift 2 中,库对真正意外的错误(抛出)与程序员本可以避免的错误(不扔,但只是让你的应用程序崩溃)。
(我不喜欢这种区别,或者至少不喜欢 Apple 做出的关于哪些错误属于哪个类别的所有具体决定。JSON API 接近荒谬在这个部门。但是……我们使用的是 API。)
NSKeyValueObserving
文档说:
It is an error to call
removeObserver:forKeyPath:
if the object has not been registered as an observer.
“这是一个错误”是 Apple 代码,表示“您有责任永远不要这样做,如果您这样做,您的应用程序将以无法捕捉的方式崩溃。”
在这些情况下,通常可以调用 API 来检查您将要做的事情的有效性。但是,据我所知,您无法通过 KVO API 调用来询问“X 是否正在观察对象 Z 的关键路径 Y?”这意味着您有三个选择:
- 弄清楚你为什么试图从你没有观察到的东西中移除一个观察者,并使用你的程序自己的内部逻辑来阻止它。
- 为“我正在观察的玩家”保留一个弱实例变量,并在尝试移除观察者之前检查它是否匹配。
- 在删除之前将自己添加为观察者。 (我很确定冗余添加是可以的。)
status
是 AVPlayer
或 AVPlayerItem
的 属性。
readyForDisplay
是 AVPlayerLayer