如何判断对象是否附加了键值观察器

Ara*_*and 141 cocoa key objective-c key-value-observing

如果你告诉一个目标c对象removeObservers:对于一个关键路径并且该关键路径尚未注册,它会破坏sads.喜欢 -

'无法删除关键路径"theKeyPath"的观察者,因为它未注册为观察者.

有没有办法确定一个对象是否有一个注册的观察者,所以我可以做到这一点

if (object has observer){
  remove observer
}
else{
  go on my merry way
}
Run Code Online (Sandbox Code Playgroud)

小智 312

试试看你的removeObserver调用吧

@try{
   [someObject removeObserver:someObserver forKeyPath:somePath];
}@catch(id anException){
   //do nothing, obviously it wasn't attached because an exception was thrown
}
Run Code Online (Sandbox Code Playgroud)

  • 对于我最有可能同意的删除咆哮的支持. (25认同)
  • Downvoted,因为你不知道这对于生产代码是不安全的,并且可能随时失败.通过框架代码引发异常不是Cocoa中的一个选项. (19认同)
  • 1+很好的答案,为我工作,我同意你的咆哮编辑之前. (12认同)
  • 这里有没有其他优雅的解决方案?这个每次使用至少需要2ms ...想象一下tableviewcell (12认同)
  • 如何在swift 2.1中使用此代码.do {try self.playerItem?.removeObserver(self,forKeyPath:"status")}抓住错误,因为NSError {print(error.localizedDescription)}收到警告. (6认同)
  • 该解决方案对于生产是安全的,并且记录良好.事实上,Apple基本上建议使用这种特定模式进行异常处理.由于Apple的零成本异常处理,这在64位系统上更快,更强大.(但我个人将'id anException'更改为'NSException*exception') (5认同)
  • 对于这种特殊情况,我们可以使用try和catch.这是我从http://nshipster.com/key-value-observing/了解到的 (2认同)
  • 我面临同样的问题,在swift中删除观察者.如何解决这个问题? (2认同)

Pet*_*sey 37

真正的问题是为什么你不知道你是否在观察它.

如果您在被观察对象的类中执行此操作,请停止.无论观察什么,它都希望继续观察它.如果你在不知情的情况下切断了观察者的通知,那么期待事情就会破裂; 更具体地说,期望观察者的状态变得陈旧,因为它没有从先前观察到的对象接收更新.

如果你在观察对象的类中这样做,只需记住你正在观察的对象(或者,如果你只观察过一个对象,你是否正在观察它).这假设观察是动态的,并且在两个不相关的对象之间; 如果观察者拥有观察者,只需在创建或保留观察者后添加观察者,并在释放观察者之前移除观察者.

作为观察者添加和删除对象通常应该发生在观察者的类中,而不是在观察对象中.

  • 不,这不是一个有趣的问题.你不应该跟踪这个; 你应该能够简单地取消注册dealloc中的所有监听器,而不关心你是否碰巧碰到了它所添加的代码路径.它应该像NSNotificationCenter的removeObserver一样工作,它不关心你是否真的有一个.这个例外只是创建了一些错误,否则就不会存在错误,这就是糟糕的API设计. (40认同)
  • 用例:您希望在viewDidUnload和dealloc中删除观察者.这将删除它们两次,如果从内存警告中卸载viewController,则会抛出异常,然后也会释放.你如何建议处理这种情况? (14认同)
  • 问题中没有任何内容涉及删除*其他*代码的观察者. (3认同)
  • @bandejapaisa:我在回答中说的很多:跟踪我是否正在观察,只是试着停止观察我是否. (2认同)

ma1*_*w28 25

FWIW,[someObject observationInfo]似乎nil如果someObject没有任何观察员.但是,我不相信这种行为,因为我没有看到它记录在案.另外,我不知道如何阅读observationInfo以获得特定的观察者.