NSManagedObject and KVO vs Documentation
I have a custom NSManagedObject
subclass, say, Person
. I also have a UIView
registered with -addObserver:forKeyPath:options:context:
to observe various properties of a Person
, some of which are persistent like "name" and others are just dumb KVO-compliant accessors unrelated to Core Data, like "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
Everything works. Whenever I send -getDrunk
or set the name
property, the view does get notified. I'm a happy man except when I read NSManagedObject
docs which state:
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
Fact 1. YES 开发者_JAVA技巧if the receiver provides automatic support for key-value observing change notifications for key, otherwise NO.
Fact 2. The default implementation for NSManagedObject returns NO for modeled properties, and YES for unmodeled properties.
Now I'm trying hard to parse the above two facts from the docs. Checking Fact 2 is easy and class Person indeed returns NO for @"name" and YES for @"drinking". But then, how does the view get notified when the name changes? KVO docs clearly say,
Using automatic observer notifications, it is not necessary to bracket changes to a property with invocations of willChangeValueForKey: and didChangeValueForKey: when mutating properties via key-value coding and key-value coding compliant methods.
So, if Person returns NO from +automaticallyNotifiesObserversForKey:
for @"name", it would seem that I have to manually wrap the name setter in will/didChangeValueForKey:
for KVO to work. However, KVO works just fine. What am I missing? What's the point in NSManagedObject
's overriding +automaticallyNotifiesObserversForKey:
and documenting it if does not seem to change standard KVO behaviour?
Please, help me regain my sanity.
Well, NSManagedObject
does provide an implementation for the name
property (as well as the - name
and - setName:
methods). I would assume that the implementations provided by Core Data do include calls to willChangeValueForKey:
and didChangeValueForKey:
.
So, although the KVO is "automatic" in the sense that you didn't have to do anything to make it work, I would imagine that it is not automatic in the sense that willChangeValueForKey:
and didChangeValueForKey:
are being called by the methods in NSManagedObject
that provide the dynamic property implementations.
I also have a UIView registered with -addObserver:forKeyPath:options:context
It is the job of the controller to take the data from the model and set it on the view, and formatting it along the way. The view should be able to display data from any model not just a Person - think title, subtitle rather than name. Also the controller can receive edits from the view and apply them to the model as well as filtering notifications from the model to prevent things being needlessly set back on the view again where they just came from.
精彩评论