Swift Observer(KVO):检查是否存在

时间:2018-09-11 12:34:01

标签: ios swift xcode key-value-observing

我有一个供用户平移的框。为此,我添加了一个观察者以检查其中心是否已更改:

self.boxView!.addObserver(self, forKeyPath: "center", options: .old, context: &BoxCenterContext)

在显示该框的动画之后添加。

关闭该框后,我将其删除为:

self.boxView!.removeObserver(self, forKeyPath: "center", context: &BoxCenterContext)

问题

用户有可能在盒子展示完成之前将盒子解雇。在添加KVO之前。

发生这种情况时,应用程序崩溃,试图删除不存在的KVO。

问题

是否有办法(在尝试删除之前)检查KVO是否存在?

4 个答案:

答案 0 :(得分:6)

observationInfo属性是在添加观察者的情况下设置的

if self.boxView!.observationInfo != nil {

   self.boxView!.removeObserver(self, forKeyPath: "center", context: &BoxCenterContext) 
}

答案 1 :(得分:5)

Apple不提供任何用于检查观察者是否存在的API,但是您可以为此管理Bool标志。就像当您注册KVO时,将isObserver bool设置为true,然后在删除观察者之前,如果isObserver为true,则需要检查isObserver true为false,因此请移除观察者,如果为false则不要做任何事情。

答案 2 :(得分:1)

根据Apple doc观察者移除代码应该包裹在@try @catch块中,因为没有API来检查特定对象是否是观察者。例如(请原谅我的目标 c):

    @try {
        [self.event removeObserver:self forKeyPath:@"eventTimeZone"];
    } @catch (NSException *exception) {
        NSLog(@"Tried to remove observer from event, but there was no observer anymore.");
    }

答案 3 :(得分:0)

使用此扩展名

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