ibiren
ibiren

Reputation: 693

NSRangeException exception with Core Data application

I am using Core Data for storing certain details of contact like RecordID, Modificationtimestamp, etc.

My app crashes with following message;

CoreData: error: Serious application error.  Exception was caught during Core Data change processing.  This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.  *** -[_PFBatchFaultingArray objectAtIndex:]: index (68) beyond bounds (57) with userInfo (null)
2012-12-12 13:10:11.585 SalesPro[351:907] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[_PFBatchFaultingArray objectAtIndex:]: index (68) beyond bounds (57)'

This is the crash log:

Last Exception Backtrace:
0   CoreFoundation                  0x389c029e __exceptionPreprocess + 158
1   libobjc.A.dylib                 0x3519797a objc_exception_throw + 26
2   CoreFoundation                  0x389c01c0 +[NSException raise:format:] + 100
3   CoreData                        0x36f656ce -[_PFBatchFaultingArray objectAtIndex:] +   142
4   CoreData                        0x3701e5ec +[NSFetchedResultsController(PrivateMethods) _insertIndexForObject:inArray:lowIdx:highIdx:sortDescriptors:] + 224
5   CoreData                        0x3701adf2 -[NSFetchedResultsController(PrivateMethods) _postprocessInsertedObjects:] + 510
6   CoreData                        0x3701ca82 -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] + 2402
7   CoreFoundation                  0x38911032 _CFXNotificationPost + 1422
8   Foundation                      0x3a073d8c -[NSNotificationCenter postNotificationName:object:userInfo:] + 68
9   CoreData                        0x36faa302 -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 74
10  CoreData                        0x36fa9862 -[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:withDeletions:withUpdates:withRefreshes:] + 294
11  CoreData                        0x36f2bc06 -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 2694
12  CoreData                        0x36f2b10a _performRunLoopAction + 266
13  CoreFoundation                  0x389956c8 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 16
14  CoreFoundation                  0x389939bc __CFRunLoopDoObservers + 272
15  CoreFoundation                  0x38993d12 __CFRunLoopRun + 738
16  CoreFoundation                  0x38906eb8 CFRunLoopRunSpecific + 352
17  CoreFoundation                  0x38906d44 CFRunLoopRunInMode + 100
18  GraphicsServices                0x346df2e6 GSEventRunModal + 70
19  UIKit                           0x3910e2f4 UIApplicationMain + 1116
20  SalesPro                        0x000a4c0c 0xa3000 + 7180
21  libdyld.dylib                   0x39ac7b1c start + 0

There is no inconsistency with numberOfRowsInSection method.

EDIT

Code for updating table view

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

    UITableView *tableView = self.table;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView cellForRowAtIndexPath:indexPath];
            break;

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

        case NSFetchedResultsChangeUpdate:
            [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation: UITableViewRowAnimationFade];
            break;
        }

    [self.table reloadData];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    [self.table endUpdates];

    [table reloadData];
}

Upvotes: 0

Views: 1771

Answers (2)

Lorenzo B
Lorenzo B

Reputation: 33428

Without further details it is difficult to say what is going on but you should implement

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView beginUpdates];
}

The method sets up the table for changes.

Finally, you should call

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}

to inform the changes are done.

reloadData method is not necessary if you have implemented - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath method correctly.

In addition, as @Mundi suggested you should call also - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo for setting up changes to your sections.

I really suggest to read the template provided by Apple at NSFetchedResultsControllerDelegate Protocol Reference.

In addition, you could take a look at Core Data on iOS 5 Tutorial: How To Use NSFetchedResultsController.

Hope that helps.

Upvotes: 2

Mundi
Mundi

Reputation: 80265

Make sure you also implement the NSFetchedResultsControllerDelegate method controller:didChangeSection:atIndex:forChangeType: to deal with more sweeping section changes.

Upvotes: 0

Related Questions