How to configure KVO in a collection (NSArray or NSSet) NSManagedObjects

I have an iPad app with a UITableViewController that implements NSFetchedResultsControllerDelegate . (The CoreDataTableViewController code from the Stanford iOS classes is mainly used.)

I have a secondary model object ( self.locations ), which is an array of Location objects, which is a subclass of NSManagedObjects . This array manages the contents of the UISegmentedControl , which filters my main fetchedResultsContoller .

You can change the contents of self.locations via popover. I want to set up some kind of observation so that my main UITableViewController can monitor changes in objects stored in self.locations and reload the UISegmentedControl if necessary.

This can also lead to a reload of the master data in the table, so I want to be careful not to reload every small modification.

I think I understand how to configure KVO on one NSManagedObject , but I'm not sure how to do this on the object contained in the array. I understand that I can use another NSFetchedResultsController, but my self.locations object self.locations not control the second UITableView, so I'm not sure if that makes sense.

+6
source share
1 answer

It's pretty easy to observe a one-to-many relationship if everything you want to know is added, deleted, replaced, or reordered. In fact, this is done exactly the same as with a regular object:

 [self addObserver:self forKeyPath:@"locations" options:0 context:NULL]; 

Then do the following to receive notifications (partially copied from Apple docs):

 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqual:@"locations"]) { // Your custom code here. } // Be sure to call the superclass implementation *if it implements it*. [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } 

Do not forget to stop at some point:

 [self removeObserver:self forKeyPath:@"locations"]; 

And, although you did not ask if you want to know if the object has any of the objects in (and not just the NSSet that you are looking here), then you should observe individual objects.

EDIT

In your comment you want to observe individual objects. This is pretty straightforward for “normal” objects, but a managed object requires a bit more work because you have to observe separate keys in the object that would look something like this:

 - (void)observeManagedObject:(NSManagedObject *)myObject { NSArray *myObjectKeys = [[[myObject entity] attributesByName] allKeys]; for (NSString *key in myObjectKeys) { [myObject addObserver:self forKeyPath:key options:0 context:nil]; } } 

And then you observe all NSManagedObjects in the array as follows:

 for (NSManagedObject *object in myArray) { [self observeManagedObject:object]; } 

Do the opposite to stop monitoring keys on the managed entity!

+10
source

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


All Articles