Swift 观察者 (KVO):检查是否存在
Swift Observer (KVO): Checking for Existence
我有一个用户可以四处移动的方框。为此,我添加了一个观察者来检查它的中心是否发生了变化:
self.boxView!.addObserver(self, forKeyPath: "center", options: .old, context: &BoxCenterContext)
这是在呈现盒子的动画之后添加的。
当框关闭时,我将其删除:
self.boxView!.removeObserver(self, forKeyPath: "center", context: &BoxCenterContext)
问题
用户有可能在盒子呈现完成之前关闭盒子,即。在添加 KVO 之前。
发生这种情况时,应用程序会在尝试删除不存在的 KVO 时崩溃。
问题
有没有办法检查 KVO 是否存在(在尝试删除之前)?
observationInfo
属性 有观察者添加时设置
if self.boxView!.observationInfo != nil {
self.boxView!.removeObserver(self, forKeyPath: "center", context: &BoxCenterContext)
}
Apple 不提供任何 API 来检查观察者是否存在,但您可以为此管理一个 Bool 标志。就像当你注册 KVO 时,你将 isObserver bool 设置为 true,然后在删除观察者之前,你需要检查 isObserver true 还是 false,如果 isObserver 是 true,那么删除观察者,如果它是 false,则不要做任何事情。
使用此扩展程序
extension NSObject {
func safeRemoveObserver(_ observer: NSObject, forKeyPath keyPath: String) {
switch self.observationInfo {
case .some:
self.removeObserver(observer, forKeyPath: keyPath)
default:
debugPrint("observer does no not exist")
}
}
}
根据 Apple doc 观察者删除代码应该包装在 @try @catch 块中,因为没有 API 检查特定对象是否是观察者。例如(见谅objective c):
@try {
[self.event removeObserver:self forKeyPath:@"eventTimeZone"];
} @catch (NSException *exception) {
NSLog(@"Tried to remove observer from event, but there was no observer anymore.");
}
我有一个用户可以四处移动的方框。为此,我添加了一个观察者来检查它的中心是否发生了变化:
self.boxView!.addObserver(self, forKeyPath: "center", options: .old, context: &BoxCenterContext)
这是在呈现盒子的动画之后添加的。
当框关闭时,我将其删除:
self.boxView!.removeObserver(self, forKeyPath: "center", context: &BoxCenterContext)
问题
用户有可能在盒子呈现完成之前关闭盒子,即。在添加 KVO 之前。
发生这种情况时,应用程序会在尝试删除不存在的 KVO 时崩溃。
问题
有没有办法检查 KVO 是否存在(在尝试删除之前)?
observationInfo
属性 有观察者添加时设置
if self.boxView!.observationInfo != nil {
self.boxView!.removeObserver(self, forKeyPath: "center", context: &BoxCenterContext)
}
Apple 不提供任何 API 来检查观察者是否存在,但您可以为此管理一个 Bool 标志。就像当你注册 KVO 时,你将 isObserver bool 设置为 true,然后在删除观察者之前,你需要检查 isObserver true 还是 false,如果 isObserver 是 true,那么删除观察者,如果它是 false,则不要做任何事情。
使用此扩展程序
extension NSObject {
func safeRemoveObserver(_ observer: NSObject, forKeyPath keyPath: String) {
switch self.observationInfo {
case .some:
self.removeObserver(observer, forKeyPath: keyPath)
default:
debugPrint("observer does no not exist")
}
}
}
根据 Apple doc 观察者删除代码应该包装在 @try @catch 块中,因为没有 API 检查特定对象是否是观察者。例如(见谅objective c):
@try {
[self.event removeObserver:self forKeyPath:@"eventTimeZone"];
} @catch (NSException *exception) {
NSLog(@"Tried to remove observer from event, but there was no observer anymore.");
}