NSManagedObject和KVO vs 文档

21

我有一个自定义的NSManagedObject子类,比如说,Person。 我还有一个UIView通过-addObserver:forKeyPath:options:context:注册来观察Person的各种属性,其中一些是持久化的,例如“name”,而其他一些则只是KVO兼容的访问器,与Core Data无关,例如“drinking”。

@interface Person : NSManagedObject
{
    BOOL drinking;
}
@property (nonatomic, retain) NSString* name;
@property (nonatomic, readonly) BOOL drinking;
@end

@implementation Person
@dynamic name;
...
- (void) getDrunk {
    [self willChangeValueForKey: @"drinking"];
    drinking = YES;
    [self didChangeValueForKey: @"drinking"];
}
...
@end

一切都正常。每当我发送-getDrunk或设置name属性时,视图确实得到了通知。我很高兴,除了当我阅读NSManagedObject文档时发现:

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
Fact 1:如果接收器为键提供自动支持的观察者变更通知,则返回YES,否则返回NO。
Fact 2:NSManagedObject的默认实现对于建模属性返回NO,对于非建模属性返回YES。
现在我正在努力从文档中解析上述两个事实。检查Fact 2很容易,类Person确实对@"name"返回NO,并对@"drinking"返回YES。但是,当名称更改时,视图如何得到通知?KVO文档明确说明:
通过使用自动观察者通知,在使用键值编码和键值编码兼容方法修改属性时,不需要使用willChangeValueForKey:和didChangeValueForKey:来限定属性的更改。
因此,如果Person从+"automaticallyNotifiesObserversForKey:"中对@"name"返回NO,似乎我必须手动将名称设置包装在will/didChangeValueForKey:中,以使KVO正常工作。然而,KVO却工作得很好。我漏掉了什么?如果不改变标准的KVO行为,那么 NSManagedObject的覆盖+automaticallyNotifiesObserversForKey:并记录它的意义是什么?
请帮我恢复理智。
2个回答

20

好的,NSManagedObject 提供了 name 属性的实现(以及 - name- setName: 方法)。我认为 Core Data 提供的实现会包括对 willChangeValueForKey:didChangeValueForKey: 的调用。

因此,虽然 KVO 在某种程度上是“自动”的,因为您不需要采取任何措施使其起作用,但我想它在另一方面并非是自动的,因为提供动态属性实现的 NSManagedObject 中的方法调用了 willChangeValueForKey:didChangeValueForKey:


2
你的解释很有道理。非常感谢! - Costique

0

我还有一个UIView通过-addObserver:forKeyPath:options:context进行了注册

控制器的工作是从模型中获取数据并在途中对其进行格式化,然后将其设置到视图上。视图应该能够显示来自任何模型的数据,而不仅仅是Person - 想想标题、副标题而不是名称。此外,控制器可以从视图接收编辑,并将它们应用于模型,以及过滤来自模型的通知,以防止将它们不必要地重新设置回视图中,这些通知刚刚来自视图。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接