views:

561

answers:

4

Hi

I have a little problem with my UITableViewController or NSFetchedResultsController. I am not sure which is the problem soure but I guess its the UITableViewController.

As I said I use a NSFetchedResultsController to fill my data into a UITableViewController. The data is sorted by date and is also displayed in sections by date-year, e.g. May 2010/June 2010/ and so on. This is displayed as the section header.

Now when I add new data, it automatically uses the current date as default, but if I want to use a date, that is currently not in the section list, e.g. April 2010 (currently May and June in the list), then this is not displayed correctly. Only when I quit the app and start it again it will show the new section headers and everything is fine.

So I somehow need to be able to refresh my list or update it. By just adding it to the context and changing it does not seem to update it.

Again, I am not sure what I need to update, if it is my NSFetchedResultsController object or the UITableViewController.

UPDATE #1:

I just figured that there is an exception in this method :

- (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];

}

This is where I move the data :

- (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:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
        //  [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];

            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            // Reloading the section inserts a new row and ensures that titles are updated appropriately.
            [tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }

}

This method is pretty much taken from the CoreDataBooks example from Apple. And this is the error :

Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. * -[NSMutableArray removeObjectAtIndex:]: index 1 beyond bounds [0 .. 0] with userInfo (null)

And after that, the edit mode (where the delete button appears) does not work anymore.

Thanks.

A: 

You need to implement the controller:didChangeSection:atIndex:forChangeType: delegate methods. In it, send insertSections:withRowAnimation:, deleteSections:withRowAnimation:, and reloadSections:withRowAnimation: messages to your table view depending on the reported change type.

Ole Begemann
Thats what I added in the question...,the exception comes after that.
elementsense
You are not even mentioning `controller:didChangeSection:atIndex:forChangeType:`.
Ole Begemann
isnt -controller:didChangeObject:atIndexPath: forChangeType:newIndexPath doing the same ?
elementsense
Well, as the documentation says, the one notifies you of changes of objects, the other one of changes of sections. Since you are apparently having problems with section changes, the problem probably lies in the method I mentioned.
Ole Begemann
I am sorry, I actually have that method implemented. I is basically copied form the CoreDataBooks example.
elementsense
Unfortunately it is not called ?!
elementsense
+2  A: 

Ok, looks like I found a solution, I just skip these

[self.tableView beginUpdates];
[self.tableView endUpdates];

and always do this.

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{

[self.tableView reloadData];

}

I will obviously give this some more logic, since the problem only occures when I want to move my data in a section that does not exist before. Until someone can give me a real solution, I will go with this one.

elementsense
I spoke with an Apple engineer at WWDC about this. He said that this was a bug in UITableView (that has been fixed in 4.0). If you are on < 4.0, just call `reloadData` like that. If you are on >= 4.0, do it like the documentation says.
Sam Soffes
A: 

I'm having pretty much the same issue ...

Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. * -[NSMutableArray removeObjectAtIndex:]: index 0 beyond bounds for empty array with userInfo (null)

This happen when i delete a object in a background thread ...

How did you manage to solve this ?

Ptitaw
This is not an answer. If you have a comment about the question, please leave a comment. Please only leave an answer if you have an answer to the question.
Sam Soffes
A: 

Adopting the fix by Apple in iPhoneCoreDataRecipes in version 1.2, the proper thing to do is to replace

// Reloading the section inserts a new row and ensures that titles are updated appropriately. [tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];

with

    [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];

(FileMerge is your friend!)

Note, there's another fix in version 1.2 that prevents erratic crashing when creating new entries. I had reported this and it was fixed within two weeks. I encourage you to file bug reports with Apple. They're far more responsive than you think, and you can expect to get the best possible fix.

oliverue