【问题标题】:Remove all observers from a class从类中删除所有观察者
【发布时间】:2015-12-17 10:57:37
【问题描述】:

在一个项目中,我有一个类“A”,还有许多其他类正在观察“A”类的属性值。

有时“A”类实例被释放并且观察失败导致崩溃!

有没有办法从“A”类中删除所有观察者?像这样的:

-(void) dealloc{
    [remove allObservers forKey:@"theKey"];
}

【问题讨论】:

  • 观察者保持对他们所观察事物的强烈引用是否合适?
  • 如果在可变数组中添加观察者并在 realloc 中撤销观察者并删除该数组的所有对象会怎样。
  • 你能告诉你如何添加观察者
  • 你能把“A”类对象作为另一个对象的属性并观察键路径吗?在 dealloc 中,您将属性设置为 nil。

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


【解决方案1】:

简而言之,遗憾的是没有。不幸的是,KVO 是为了 it gets you in the end 而制作的。

我之前也纠结过这个东西,找到了以下两种解决方法:

  1. 使用代理方法在被观察者中注册观察,这将维护对观察者的弱引用列表。
    理想情况下,您还需要一个代理方法来删除观察者,以便相应地更新您的列表(尽管,由于它们是列表中的弱引用,因此如果某些观察者使用标准 KVO 而不是您的代理方法,然后释放自身)。
    如果您的观察者被释放,它应该通知所有观察者(使用协议),或者直接将它们删除。对于最后一个,使用异常也可能会派上用场(我知道异常在 Obj-C 中是邪恶的,但是该怎么办):

    @try 
    {
        [self removeObserver:observee forKeyPath:@"path"];
    }
    @catch (NSException * __unused exception) {}
    
  2. 使用来自 KVO 的一些抽象。想到了几个项目,例如RZDataBindingMAKVONotificationCenter(尽管它的名字,它实际上与KVO 有关)

【讨论】:

    【解决方案2】:

    您应该让“A”类保持活动状态,直到有其他对象观察其属性值。也许它被释放是因为你没有正确处理它的引用。

    您应该检查“A”是否需要“强”引用。当您不再需要“A”时(即:您正在弹出一个视图控制器,您正在刷新一个表格,您正在清除一个滚动视图),您还应该删除任何附加到它的观察者(并且能够做到它)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多