【问题标题】:Observing self in Cocoa在 Cocoa 中观察自我
【发布时间】:2009-08-09 22:33:02
【问题描述】:

在 Cocoa 中,addObserver:forKeyPath:options:context: 保留“既不是接收者,也不是观察者”。因此,我假设允许观察自我;也就是说,这样做是完全有效的

[self addObserver:self forKeyPath...]

只要你记得注销self作为观察者作为dealloc中的第一件事。

这个假设正确吗?

【问题讨论】:

    标签: cocoa key-value-observing


    【解决方案1】:

    是的,没有任何理由你不能观察自我。但就像你说的,就像任何 KVO 观察一样,请确保在解除分配之前将自己作为观察者移除。

    为了记录,如果您只是在谈论一个简单的键,那么另一种方法是编写自定义设置器并在设置器中执行您需要的任何代码。这种风格使得调用 setter 的全部效果更加明显。不过,KVO 方式更灵活一些,并且适用于包含多个组件的关键路径。

    【讨论】:

      【解决方案2】:

      我按照布赖恩·韦伯斯特所说的去做。这是一个例子:

      //.h
      ...
      @property(readwrite, retain, setter=setMyPropertySynth:) id myProperty;
      -(void)setMyProperty:(id)newValue;
      ....
      
      
      //.m
      ...
      @synthesize myProperty;
      
      -(void)setMyProperty:(id)newValue
      {
          //add code here
      
          [self setMyPropertySynth:newValue];
      
          //add more code here
      }
      ...
      

      【讨论】:

      • 这不是一个好主意。通常预计 obj.foo = bar; 应该等同于 [obj setFoo:bar]; 并且偏离此模式会使其他正在阅读/维护您的代码的人感到困惑
      • @rpetrich 我同意这不是一个好主意(我在 18 个月前写了这个答案),但出于不同的原因。我将不再使用@synthesize;我现在将编写整个 getter 和 setter。一些额外行的额外负担超过了在精神上遵循额外方法调用的成本(我仍然使用@property)。我不同意 setter(或 getter)中的副作用本质上是不好的。应尽可能避免使用它们。例如,设置hypotheticalQueryObject.maxResults = 4; 可以合法地触发另一个搜索。
      • @rpetrich 这实际上是有保证的。 obj.foo = bar; 始终使用所提供的 setFoo: 的任何实现(即使您已经覆盖了合成的实现)。
      • @Jonathan Sterling:实际上,并非如此。在这种情况下,obj.myProperty = foo; 等效于 [obj setMyPropertySynth:foo] 而不是 [obj setMyProperty:foo]。请重读本尼迪克特的回答。
      【解决方案3】:

      不要删除-dealloc 中的观察者。为什么?因为当您打开垃圾收集器时,事情将停止工作; -dealloc 永远不会被调用。对于内存相关清理代码,您应该只使用-dealloc-finalize 方法。

      【讨论】:

      • 只需将其设置为对象生命周期的一部分。如果创建它的事物告诉它要观察什么以及何时停止观察它,那么您就是在注入依赖项,这使您的对象更易于重用和测试。
      • ...但更容易使用不正确,并破坏 Cocoa 内存管理。如果每个创建者还必须知道创建的对象必须观察某某(特别是如果那是它本身),那么我们已经将私有信息移动到调用者中,这很糟糕。更糟糕的是,如果我需要一个“现在就摧毁你”的方法来撤销这个观察,那么 GC 的全部意义就消失了。我们最好的解决方案是将非内存管理部分复制到 dealloc 并完成(可能提升到共享例程)。这也包括 NSNotificationCenter removeObserver。
      • 我认为在 ARC 中你仍然使用 dealloc,但唯一的区别是你不在那里调用 [super dealloc]。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-06
      • 2011-12-11
      • 1970-01-01
      相关资源
      最近更新 更多