5 cocoa objective-c key-value-observing
这是一个简单的例子,对于这个问题应该足够了.
@interface MyClass: NSObject {
Person *_owner;
}
@property (strong) Person *owner;
@property (readonly) BOOL hasSomething;
@end
@implementation
// other code here like -init
- (void)setOwner:(Person *)newOwner
{
[_owner removeObserver:self forKeyPath:@"stuff"];
_owner = newOwner;
[_owner addObserver:self forKeyPath:@"stuff" options:0 context:NULL];
}
- (Person*)owner
{
return _owner;
}
- (BOOL)hasSomething
{
return owner.stuff > 0;
}
- (void)observeValueForKeyPath:(NSString*)kp ofObject:(id)obj change:(NSDictionary*)ch context:(void*)c
{
if ([kp isEqualtToString:@"stuff"]) {
[self willChangeValueForKey:@"hasSomething"];
[self didChangeValueForKey:@"hasSomething"];
}
}
@end
Run Code Online (Sandbox Code Playgroud)
在我的例子中,任何绑定的东西hasSomething都没有被正确地通知值的变化.我错过了什么?
小智 3
我的解决方法:
我最初通过直接绑定到我想要跟踪的值来解决这个问题。在给出的示例中,它看起来像arrangedObjects.owner.stuff。
我的解决方案: 后来我重新审视了代码,发现我所得到的基本上是正确的。这个想法是封装对象层次结构的内部工作(如果您像上面的解决方法一样绑定整个路径,则无法实现)。在问题中,我将问题简化为具有两个级别的层次结构:MyClass -> Person。我的代码实际上涉及更多的层次和一对多的关系。层次结构中的元素之一是没有正确观察其子元素。
丹尼斯建议我看一下,-automaticallyNotifiesObserversForKey:我就看了。NO根据我的理解,如果您想在属性的 setter 方法中手动发送通知,您可能希望该方法返回。否则,您的通知会与自动通知发生冲突。
- (void)setHasSomething:(BOOL)newVal
{
[self willChangeValueForKey:@"hasSomething"];
// ...
[self didChangeValueForKey:@"hasSomething"];
}
Run Code Online (Sandbox Code Playgroud)
由于只读属性没有 setter 方法,因此它并不能解决我的问题。
经验教训: 1)正确观察孩子;2)寻求帮助时不要过度简化你的问题。
| 归档时间: |
|
| 查看次数: |
1539 次 |
| 最近记录: |