【问题标题】:iOS App crashes because KVO observer is not observing anymoreiOS 应用程序崩溃,因为 KVO 观察者不再观察
【发布时间】:2017-04-01 18:20:20
【问题描述】:

有没有办法知道是否有对象在监听视图控制器的键路径。例如,我的视图控制器中有

[tabBarController addObserver:self
     forKeyPath:@"selectedViewController"
     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
     context:&PrivateKVOContext
]; (edited)

我想知道我的 tabbarcontroller 是否可以知道我的 viewcontroller 是否正在侦听该键路径

原因是我的应用程序崩溃了,因为标签栏控制器仍然认为我的视图控制器正在侦听该键路径,即使我的视图控制器已被释放

在我的视图控制器的dealloc方法中,我把[tabBarController removeObserver:self forKeyPath:@"selectedViewController”];作为观察者移除了自己

【问题讨论】:

  • 如果观察者没有被删除,请尝试在viewWillDisappear中写入[[NSNotificationCenter defaultCenter] removeObserver:observerObjectHere]
  • 有点切线但是为什么标签栏控制器中的视图控制器应该在选择不同的标签时关心?这听起来像是一个糟糕的设计。
  • 你为什么不继承 tabBarController 并创建协议,使用它你将能够发送 selectedViewController 已更改的委托消息。这将是更清晰的解决方案。

标签: ios objective-c key-value-observing


【解决方案1】:

遗憾的是没有。无法检查哪些对象当前正在观察其他对象。

因此,通常建议您将 removeObserver: 放在与 addObserver: 相同的补充方法中,这样它们就会被可靠地调用相同的次数。

在这种情况下,由于您将其放入在视图控制器生命周期结束时调用的 dealloc 中,因此您应该将 addObserver: 放入您的 init 方法中,该方法将在一开始就被调用。

【讨论】:

    【解决方案2】:

    这取决于观察者是否真的在使用,在你的代码中,试试这个:

    - (void)dealloc {
    
        @try {
            [[NSNotificationCenter defaultCenter] removeObserver:Notification_Location_Ready];
        } @catch (NSException *exception) {
    
        } @finally {
    
        }
    }
    

    【讨论】:

    • 不要使用这个,拜托。 try-catch 完全是不好的做法。这只隐藏了代码中明显的错误,并没有修复它。相反,他应该创建一些结构来保留对观察者的引用,然后在适当的时候删除它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    相关资源
    最近更新 更多