21

我有一个自定义NSManagedObject子类,比如Person. 我还UIView注册了一个-addObserver:forKeyPath:options:context:来观察 a 的各种属性Person,其中一些是持久的,如“名称”,而另一些只是与核心数据无关的愚蠢的 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文档时:

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key

事实 1. 如果接收器为键的键值观察更改通知提供自动支持,则为 YES,否则为 NO。

事实 2. NSManagedObject 的默认实现对建模属性返回 NO,对未建模属性返回 YES。

现在我正在努力从文档中解析上述两个事实。检查事实 2 很容易,并且类 Person 确实为 @"name" 返回 NO,为 @"drinking" 返回 YES。但是,当名称更改时,视图如何得到通知?KVO 文档清楚地说,

使用自动观察者通知,当通过键值编码和键值编码兼容的方法改变属性时,没有必要通过调用 willChangeValueForKey: 和 didChangeValueForKey: 对属性的更改括起来。

因此,如果 Person 从 @"name" 返回 NO +automaticallyNotifiesObserversForKey:,看来我必须手动将名称设置器包装在will/didChangeValueForKey:KVO 中才能工作。但是,KVO 工作得很好。我错过了什么?如果似乎没有改变标准 KVO 行为,那么NSManagedObject覆盖和记录它有什么意义?+automaticallyNotifiesObserversForKey:

请帮助我恢复理智。

4

2 回答 2

20

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

因此,尽管 KVO 在某种意义上是“自动的”,因为您不必做任何事情就可以使其工作,但我想它不是自动的,willChangeValueForKey:并且didChangeValueForKey:NSManagedObject提供动态的方法调用属性实现。

于 2010-09-16T16:14:42.013 回答
0

I also have a UIView registered with -addObserver:forKeyPath:options:context

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

于 2020-08-09T16:36:00.793 回答