KVO object properties within the to-many relationship

I have a Core Data to-many relationship consisting of Parent <--- → Child. I would like to configure a mechanism for monitoring a key value so that when a property (for example, firstName, lastName) is changed on any of the Child objects, it triggers a notification. Using the standard KVO syntax:

[self.parentObject addObserver:self forKeyPath:@"children" options:NSKeyValueObservingOptionNew context:NULL] 

it only notifies when the relationship itself changes (i.e. a child is added or removed from the relationship), and not when the property of one of these child objects changes. Obviously, this is how it was designed to work, so there is nothing wrong with that, but how can I use KVO instead to achieve my desired requirement?

Thanks in advance!

+4
source share
2 answers

AFAIK there is no built-in way to monitor the properties of a collection object with a single line of code. Instead, you should add / remove observers when an object is inserted / removed from your collection.

An explanation and an example project can be found here: https://web.archive.org/web/20120319115245/http://homepage.mac.com/mmalc/CocoaExamples/controllers.html (See "Watching the collection is not something the same as observing the properties of objects in a collection ").

Update:
The link is broken - I changed it to a snapshot of archive.org.

+4
source

A little late answer, but maybe it will be useful for those who do it.

You can configure the NSFetchedResultsController for the child with the predicate @"parent == %@", child , and then add the controller as a delegate for this fetchedResultController. The delegate will be called when any of the child’s properties changes, as well as when they are added, etc. The following is sample code. I also added a sort descriptor to sort children by their name on

 ... 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 nice piece of code for this

+3
source

Source: https://habr.com/ru/post/1384044/


All Articles