在使用对象观察值时addObserver:forKeyPath:options:context:,最终您将要调用removeObserver:forKeyPath:该对象以便稍后进行清理.在此之前,是否可以检查对象是否实际上正在观察该属性?
我试图在我的代码中确保一个对象只在需要时删除了一个观察者,但在某些情况下,观察者可能会尝试将自己移除两次.我正在努力防止这种情况,但为了以防万一,我一直在试图弄清楚是否有办法首先检查我的代码是否真的是一个东西的观察者.
使用KVO而不是NSNotifications 的更"通用"(以及我的opion更强大)功能是否有任何优势?
我有一些使用KVO的代码,并且在多个地方都有addObserver:forKeyPath:和removeObserver:forKeyPath : . 该应用程序偶尔会崩溃"无法移除观察者的关键路径".
我想知道是否可以安全地尝试/捕获异常以防止应用程序崩溃.我知道这不是处理KVO的最佳方法,但我需要花一些时间才能清理代码.
cocoa objective-c key-value-observing nsnotificationcenter ios
为了防止添加多个观察者,我在添加观察者之前移除观察者,这是推荐的:iPhone - 测试是否存在通知.
[[self getPlayer] removeObserver:self forKeyPath:@"position"];
[[self getPlayer] addObserver:self forKeyPath:@"position" options:NSKeyValueObservingOptionNew context:nil];
Run Code Online (Sandbox Code Playgroud)
但是,这样做会导致异常: __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
有关如何检查关键路径是否已存在观察者的任何想法,如果是这样,不添加新的想法?
我在代码中添加了一个观察者,然后在dealloc和viewWillDisappear中将其删除但是我仍然收到错误说明
***由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'类的MyController2的实例0x167e5980被释放,而键值观察者仍然注册了它.
Run Code Online (Sandbox Code Playgroud)Current observation info: <NSKeyValueObservationInfo 0x16719f90> ( <NSKeyValueObservance 0x16719fb0: Observer: 0x167e5980, Key path: dataContainer.report, Options: <New: YES, Old: YES, Prior: NO> Context: 0x0, Property: 0x1677df30> )'
我创建了一个控制器,MyController并从中派生出一个新的控制器MyController2.现在我加入了KVO MyController2.
- (void)viewDidLoad {
[super viewDidLoad];
[self addObserver:self forKeyPath:@"dataContainer.report" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
Run Code Online (Sandbox Code Playgroud)
然后在observeValueForKeyPath中: -
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
id oldC = [change objectForKey:NSKeyValueChangeOldKey];
id newC = [change objectForKey:NSKeyValueChangeNewKey];
if([keyPath isEqualToString:@"dataContainer.report"]) {
if (oldC != newC) {
//Remove Observer …Run Code Online (Sandbox Code Playgroud)