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.");
    }