【发布时间】:2011-04-13 07:07:48
【问题描述】:
我有一个自定义的NSManagedObject 子类,比如Person。我还有一个在-addObserver:forKeyPath:options:context: 注册的UIView 以观察Person 的各种属性,其中一些是持久的,如“名称”,而另一些只是与Core Data 无关的符合KVO 的愚蠢访问器,如“饮酒”。
@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 docs 声明:
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
事实 1. 如果接收器提供对 key-value 观察更改通知的自动支持,则为 YES,否则为 NO。
事实 2. NSManagedObject 的默认实现对建模属性返回 NO,对未建模属性返回 YES。
现在我正在努力从文档中解析上述两个事实。检查事实 2 很容易,并且类 Person 确实为 @"name" 返回 NO,为 @"drinking" 返回 YES。但是,当名称更改时,视图如何得到通知? KVO 文档清楚地说,
使用自动观察者通知,当通过键值编码和键值编码兼容的方法改变属性时,不需要通过调用 willChangeValueForKey: 和 didChangeValueForKey: 来括住对属性的更改。
因此,如果 Person 从 +automaticallyNotifiesObserversForKey: 为 @"name" 返回 NO,看来我必须手动将名称设置器包装在 will/didChangeValueForKey: 中才能使 KVO 工作。但是,KVO工作得很好。我错过了什么? NSManagedObject 覆盖 +automaticallyNotifiesObserversForKey: 并记录它似乎没有改变标准 KVO 行为有什么意义?
请帮我恢复理智。
【问题讨论】:
标签: cocoa core-data key-value-observing nsmanagedobject