title: Changing a managed object property doesn't trigger NSFetchedResultsController to update the table view
body: <p>I have a <strong>fetchedResultsController</strong> with a predicate, where <strong>"isOpen == YES"</strong></p>
  
  <p>When calling for <strong>closeCurrentClockSet</strong>, I set that property to <strong>NO</strong>. Therefore, it should no longer appear on my tableView.</p>
  
  <p>For Some Reason, this is not happening. </p>
  
  <p>Can someone help me figure this out please?</p>
  
  <pre><code>-(void)closeCurrentClockSet
  {
  
      NSPredicate * predicate = [NSPredicate predicateWithFormat:@"isOpen == YES"];
  
      NSArray *fetchedObjects =
          [self fetchRequestForEntity:@"ClockSet"
                        withPredicate:predicate
               inManagedObjectContext:[myAppDelegate managedObjectContext]];
  
      ClockSet *currentClockSet = (ClockSet *)fetchedObjects.lastObject;
  
      [currentClockSet setIsOpen:[NSNumber numberWithBool:NO]];
  
  }
  </code></pre>
  
  <p>--</p>
  
  <p>I have a couple of methods more, using the <strong>exact same approach</strong>,
  by calling a custom <strong>fetchRequestForEntity:withPredicate:inManagedObjectContext</strong> method.</p>
  
  <p>In those methods, when changing a property, tableView get correctly updated!
  But this one above (<strong>closeCurrentClockSet</strong>), doesn't! I can't figure out why.</p>
  
  <p>--</p>
  
  <p>My implementation for my fetchedResultsController, is from Apple's documentation.</p>
  
  <p><strong>Also, another detail. If I send my App, to the background. Close it and re-open, tableView shows updated as it should!</strong></p>
  
  <p>I have tried my best to follow previous questions here on stackOverflow. No luck. I also NSLogged this to the bone.
  The object is getting correctly fetched. It is the right one. <strong>isOpen Property</strong> is being correctly updated to <strong>NO</strong>. But for some reason, my fetchedResultsController doesn't update tableView.</p>
  
  <p>I did try a couple a "hammer" solutions, like reloadData and calling performFetch. But that didn't work. Or would make sense to used them...</p>
  
  <p><strong>EDIT: scratch that, it DID work, calling reloadData imediatly after performFetch on my resultsController</strong> but using reloadData is hammering a solution. Plus, it takes out all animations. I want my controller to auto-update my tableView.</p>
  
  <p>Can someone help me figure this out?</p>
  
  <p>Any help is greatly appreciated!</p>
  
  <p>Thank you,</p>
  
  <p>Nuno</p>
  
  <p>EDIT:</p>
  
  <p>The complete implementation.</p>
  
  <p>fetchedResultsController is pretty standard and straightforward. Everything else is from Apple's documentation</p>
  
  <pre><code>- (NSFetchedResultsController *)fetchedResultsController
  {
  
      if (_fetchedResultsController) {
          return _fetchedResultsController;
      }
  
      NSManagedObjectContext * managedObjectContext = [myAppDelegate managedObjectContext];
  
      NSEntityDescription *entity  =
          [NSEntityDescription entityForName:@"ClockPair"
                      inManagedObjectContext:managedObjectContext];
  
      NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
          [fetchRequest setEntity:entity];
  
      NSString *predicate = [NSString stringWithFormat: @"clockSet.isOpen == YES"];
          [fetchRequest setPredicate: [NSPredicate predicateWithFormat:predicate]];
  
      NSSortDescriptor *sortDescriptor1 =
          [[NSSortDescriptor alloc] initWithKey:@"clockIn" ascending:NO];
  
      NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
  
          [fetchRequest setSortDescriptors:sortDescriptors];
          [fetchRequest setFetchBatchSize:20];
  
      NSFetchedResultsController *theFetchedResultsController =
          [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                              managedObjectContext:managedObjectContext
                                                sectionNameKeyPath:nil
                                                         cacheName:@"Root"];
  
  
      _fetchedResultsController = theFetchedResultsController;
      _fetchedResultsController.delegate = self;
  
      return _fetchedResultsController;
  
  }
  </code></pre>
  
  <h2>--</h2>
  
  <p>Boilerplate code from Apple's documentation:</p>
  
  <pre><code>- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
  {
      // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
      [self.tableView beginUpdates];
  }
  
  
  
  - (void)controller:(NSFetchedResultsController *)controller
     didChangeObject:(id)anObject
         atIndexPath:(NSIndexPath *)indexPath
       forChangeType:(NSFetchedResultsChangeType)type
        newIndexPath:(NSIndexPath *)newIndexPath
  {
  
      UITableView *tableView = self.tableView;
  
      switch(type) {
  
          case NSFetchedResultsChangeInsert:
  
              [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                               withRowAnimation:UITableViewRowAnimationTop];
  
              break;
  
          case NSFetchedResultsChangeDelete:
  
              [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                               withRowAnimation:UITableViewRowAnimationFade];
  
              break;
  
          case NSFetchedResultsChangeUpdate:
  
              [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                               withRowAnimation:UITableViewRowAnimationFade];
  
              [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                               withRowAnimation:UITableViewRowAnimationFade];
  
              break;
  
          case NSFetchedResultsChangeMove:
  
              [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                               withRowAnimation:UITableViewRowAnimationLeft];
  
              [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                               withRowAnimation:UITableViewRowAnimationTop];
  
              break;
      }
  }
  
  
  
  - (void)controller:(NSFetchedResultsController *)controller
    didChangeSection:(id )sectionInfo
             atIndex:(NSUInteger)sectionIndex
       forChangeType:(NSFetchedResultsChangeType)type
  {
  
      UITableView *tableView = self.tableView;
  
      switch(type) {
  
          case NSFetchedResultsChangeInsert:
  
              [tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
                       withRowAnimation:UITableViewRowAnimationFade];
  
              break;
  
          case NSFetchedResultsChangeDelete:
  
              [tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
                       withRowAnimation:UITableViewRowAnimationFade];
  
              break;
      }
  }
  
  
  
  - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
  {
      // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
      [self.tableView endUpdates];
  }
  </code></pre>
  
  <p><strong>1ST UPDATE:</strong> </p>
  
  <p>Tracking <strong>[managedObjectContext hasChanges]</strong> does return YES, as it should. But fetchedResultsController doesn't update the tableView</p>
  
  <p><strong>2ND UPDATE</strong></p>
  
  <p>didChangeObject:atIndexPath: <strong>does not get called</strong> for this particular case!
  I have 2 more methods, with the EXACT same code, they just happen to be a different entity. And they work perfectly. Thank you @Leonardo for pointing this out</p>
  
  <p><strong>3TH UPDATE</strong> this method, follows the same rules. But does actually work.</p>
  
  <pre><code>- (void)clockOut
  {
      NSPredicate * predicate = [NSPredicate predicateWithFormat:@"isOpen == %@", [NSNumber numberWithBool:YES]];
  
      NSArray * fetchedObjects =
          [self fetchRequestForEntity:@"ClockPair"
                        withPredicate:predicate
               inManagedObjectContext:[myAppDelegate managedObjectContext]];
  
      ClockPair *aClockPair = (ClockPair *)fetchedObjects.lastObject;
  
      aClockPair.clockOut = [NSDate date];
      aClockPair.isOpen   = [NSNumber numberWithBool:NO];
  
  
  }
  </code></pre>
  
  <p>Anyone has any other ideas for what I might be missing?</p>
  
  <p>Thank you,</p>
  
  <p>Nuno</p>