Question

Given a Core Data Entity called Book, what would be the best way to get a count of how many Books there are, in total, and display this total in a UILabel? The UILabel would need to update as book objects were created/deleted (potentially by other objects elsewhere in the app).

Actually counting the books isn't difficult. My question is more how do we get updates as this count changes?

  • Perhaps override willSave/delete/etc on the Book managed object?
  • KVO (but how do we do this on the entire Entity rather than a single object?)
  • Something else?
Was it helpful?

Solution 3

As already suggested, you could subscribe to NSManagedObjectContextObjectsDidChangeNotification and try to analyze it. I see two disadvantages in this. First, this notification is called a lot and on any change in any object. Calls will not literally happen at the moment when the change happens, but still any change is reported in this notification. Second, the subscriber needs to know all the contexts where the new Book is created. You might think of subscribing to this notification with nil for context to receive this notification for all the contexts. But this is even more overwhelming and dangerous, and not recommended by Apple (you will receive this notification also for the contexts that you don’t own).

What I would recommend for each place that creates a Book to have its own notification. Like XYBookAddControllerDidAddBookNotification, XYBookListControllerDidDeleteBookNotification and so on. In this case:

  1. The place that displays counts doesn’t have to know anything about the context where change was made.
  2. The place that displays will only respond to specific add/remove events instead of analyzing heavy traffic of objects-did-change notification.

OTHER TIPS

You can listen for the notification (NSManagedObjectContextObjectsDidChangeNotification) relating to core data changes and update your UI from that.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDataModelChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:myManagedObjectContext];

- (void)handleDataModelChange:(NSNotification *)notification;
{
  NSSet *updatedObjects  = notification.userInfo[NSUpdatedObjectsKey];
  NSSet *deletedObjects  = notification.userInfo[NSDeletedObjectsKey];
  NSSet *insertedObjects = notification.userInfo[NSInsertedObjectsKey];  

  // update your UI with the new count
}

NB: dont forget to remove yourself,

- (void)dealloc;
{
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

You could create a NSFetchedResultsController to fetch book objects, then implement it's delegate methods. Reference:

NSFetchedResultsController

NSFetchedResultsControllerDelegate Protocol

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top