Cocoa 在可可中观察自我

Cocoa 在可可中观察自我,cocoa,key-value-observing,Cocoa,Key Value Observing,在Cocoa中,addObserver:forKeyPath:options:context:保留“既不是接收者,也不是观察者”。因此,我假设观察自我是允许的;也就是说,这样做是完全正确的 [自添加观察者:自分叉路径…] 只要您记得在dealloc中首先注销作为观察者的self 这个假设正确吗?是的,没有任何理由你不能观察自我。但正如你所说,就像任何KVO观察一样,在被解除分配之前,确保将自己作为观察者移除 作为记录,如果您只是在谈论一个简单的键,那么另一种方法是编写一个自定义setter并在s

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

[自添加观察者:自分叉路径…]

只要您记得在dealloc中首先注销作为观察者的
self


这个假设正确吗?

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


作为记录,如果您只是在谈论一个简单的键,那么另一种方法是编写一个自定义setter并在setter中执行您需要的任何代码。这种风格使调用setter的全部效果更加明显。尽管KVO方式有点灵活,它可以处理包含多个组件的关键路径。

我照Brian Webster说的做。下面是一个例子:

//.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
}
...

不要删除
-dealoc
中的观察者。为什么?因为当你打开垃圾收集器时,东西就会停止工作<代码>-dealloc从未被调用。对于与内存相关的清理代码,只需使用
-dealoc
-finalize
方法即可。

只需将其设置为对象生命周期的一部分即可。如果创建对象的对象告诉它要观察什么,以及何时停止观察,那么您正在注入依赖项,这使得您的对象更容易重用和测试……但更容易错误使用,并破坏了Cocoa内存管理。如果每个创建者也必须知道所创建的对象必须观察某某(特别是如果它本身),那么我们已经将私有信息移动到了调用者中,这是不好的。更糟糕的是,如果我需要一个“立即摧毁你”的方法来撤销这个观察,那么GC的整个意义就消失了。我们拥有的最佳解决方案是将非内存管理片段复制到dealoc并完成(可能提升到共享例程)。这也包括NSNotificationCenter removeObserver。我认为在ARC中您仍然使用dealloc,但是唯一的区别是您在那里不调用[super dealloc]。这不是一个好主意。通常预期
obj.foo=bar
应等同于
[obj setFoo:bar]和偏离此模式将使正在阅读/维护您的code@rpetrich我同意这不是一个好主意(我在18个月前写下了这个答案),但原因不同。我不再使用
@synthesis
;我现在要写整个getter和setter。额外的几行代码所带来的额外负担超过了在精神上遵循额外方法调用的成本(我仍然使用
@property
)。我不同意二传手(或二传手)的副作用本质上是坏的。在可能的情况下,应避免使用这些方法。例如,设置
hypoticalqueryobject.maxResults=4
可以合法地触发另一个搜索。@rpetrich这实际上是有保证的<代码>obj.foo=条形图
总是使用提供的
setFoo:
的任何实现(即使您已经覆盖了一个合成的实现)。@Jonathan Sterling:事实上,它不是。在这种情况下,
obj.myProperty=foo
相当于
[obj setMyPropertySynth:foo]
而不是
[obj setMyProperty:foo]
。一定要重读本尼迪克特的回答。