问题
I have a Core Data to-many relationship consisting of Parent <--->> Child. I would like to setup a key-value observing mechanism such that when a property (e.g. firstName, lastName) on any of the Child objects changes it triggers a notification. When using the standard KVO syntax:
[self.parentObject addObserver:self forKeyPath:@"children" options:NSKeyValueObservingOptionNew context:NULL]
this only notifies when the relationship itself is modified (i.e. a Child object is added or removed from the relationship), rather than when a property of one of those Child objects changes. Obviously this is how it was designed to operate, so there's nothing wrong with that happening, but how can I instead use KVO to achieve my desired requirement?
Thanks in advance!
回答1:
AFAIK there is no built-in way to observe collection object properties with a single line of code. Instead you have to add/remove observers when the object is inserted/removed from your collection.
An explanation and a sample project can be found over here: https://web.archive.org/web/20120319115245/http://homepage.mac.com/mmalc/CocoaExamples/controllers.html (See the "Observing a collection is not the same as observing the properties of the objects in a collection" section)
Update:
The Link broke - I changed it to an archive.org snapshot.
回答2:
A bit of a late answer, but maybe it will be useful to someone who googles this.
You can setup an NSFetchedResultsController for the entity child with the predicate @"parent == %@", childand then add your controller as a delegate to that fetchedResultController. The delegate will be called when any of the properties of the child changes, as well as when they are added etc.
An example code follows. I have also added a sort descriptor to sort the children by their name to the
...
NSFetchRequest* fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Child"];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"parent = %@", parent];
self.fetchResultsController.fetchRequest.predicate = predicate;
self.fetchResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest managedObjectContext:context
sectionNameKeyPath:nil cacheName:nil];
self.fetchResultsController.delegate = self;
...
Then you implement the delegate method
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
And any other delegate method you need for your implementation (the documentation has a very good code snippet for this
来源:https://stackoverflow.com/questions/8336982/kvo-object-properties-within-to-many-relationship