【发布时间】:2009-08-09 22:33:02
【问题描述】:
在 Cocoa 中,addObserver:forKeyPath:options:context: 保留“既不是接收者,也不是观察者”。因此,我假设允许观察自我;也就是说,这样做是完全有效的
[self addObserver:self forKeyPath...]
只要你记得注销self作为观察者作为dealloc中的第一件事。
这个假设正确吗?
【问题讨论】:
在 Cocoa 中,addObserver:forKeyPath:options:context: 保留“既不是接收者,也不是观察者”。因此,我假设允许观察自我;也就是说,这样做是完全有效的
[self addObserver:self forKeyPath...]
只要你记得注销self作为观察者作为dealloc中的第一件事。
这个假设正确吗?
【问题讨论】:
是的,没有任何理由你不能观察自我。但就像你说的,就像任何 KVO 观察一样,请确保在解除分配之前将自己作为观察者移除。
为了记录,如果您只是在谈论一个简单的键,那么另一种方法是编写自定义设置器并在设置器中执行您需要的任何代码。这种风格使得调用 setter 的全部效果更加明显。不过,KVO 方式更灵活一些,并且适用于包含多个组件的关键路径。
【讨论】:
我按照布赖恩·韦伯斯特所说的去做。这是一个例子:
//.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]; 并且偏离此模式会使其他正在阅读/维护您的代码的人感到困惑
@synthesize;我现在将编写整个 getter 和 setter。一些额外行的额外负担超过了在精神上遵循额外方法调用的成本(我仍然使用@property)。我不同意 setter(或 getter)中的副作用本质上是不好的。应尽可能避免使用它们。例如,设置hypotheticalQueryObject.maxResults = 4; 可以合法地触发另一个搜索。
obj.foo = bar; 始终使用所提供的 setFoo: 的任何实现(即使您已经覆盖了合成的实现)。
obj.myProperty = foo; 等效于 [obj setMyPropertySynth:foo] 而不是 [obj setMyProperty:foo]。请重读本尼迪克特的回答。
不要删除-dealloc 中的观察者。为什么?因为当您打开垃圾收集器时,事情将停止工作; -dealloc 永远不会被调用。对于内存相关清理代码,您应该只使用-dealloc 和-finalize 方法。
【讨论】: