我有一个自定义NSManagedObject
子类,比如Person
。我还在UIView
注册-addObserver:forKeyPath:options:context:
来观察Person
的各种属性,其中一些属性像“name”一样持久,而其他属性只是与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
文件说明:
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
事实1.如果接收者为键的键值观察变化通知提供自动支持,则为YES,否则为NO。
事实2. NSManagedObject的默认实现为建模属性返回NO,为未建模属性返回YES。
现在我正在努力解析文档中的上述两个事实。检查事实2很简单,类人确实为@“name”返回NO,为@“drink”返回YES。但是,当名称发生变化时,视图如何得到通知? KVO文档清楚地说,
使用自动观察器通知时,没有必要通过调用willChangeValueForKey:和didChangeValueForKey来对带有调用属性的属性进行更改:通过键值编码和符合键值编码的方法改变属性。
因此,如果Person从+automaticallyNotifiesObserversForKey:
为@“name”返回NO,那么我似乎必须在will/didChangeValueForKey:
中手动包装名称设置器才能使KVO正常工作。但是,KVO 正常。我错过了什么? NSManagedObject
覆盖+automaticallyNotifiesObserversForKey:
并记录它的重点是什么似乎没有改变标准的KVO行为?
请帮助我恢复理智。
答案 0 :(得分:18)
好吧,NSManagedObject
确实提供了name
属性(以及- name
和- setName:
方法)的实现。我假设Core Data提供的实现包括对willChangeValueForKey:
和didChangeValueForKey:
的调用。
所以,尽管KVO在某种意义上是“自动的”,你不需要做任何事情来使它工作,但我会想象它{em>不是自动的{{{ 1 {}和willChangeValueForKey:
由didChangeValueForKey:
中提供动态属性实现的方法调用。
答案 1 :(得分:0)
I also have a UIView registered with -addObserver:forKeyPath:options:context
控制器的工作是从模型中获取数据并将其设置在视图上,并一路格式化。视图应该能够显示来自任何模型的数据,而不仅仅是个人-考虑标题,副标题而不是名称。控制器还可以从视图中接收编辑,并将其应用到模型,并过滤来自模型的通知,以防止不必要的事情再次放回到原来的视图上。