Search code examples
iosobjective-cuitableviewcore-datansfetchedresultscontroller

insertRowsAtIndexPaths index 3 beyond bounds at endUpdates


I'm trying to make something like a NSFetchedResultsController with multiple queries. I'm planning to fetch the data and saving the results to NSArray. But whenever I try to scroll quickly the endUpdates raises an index 3 beyond bounds exception.

The following code is the code to add more people to the array. I'm calling this method when cellForRowAtIndexPath is called for the the last element. Please let me know if i'm doing anything wrong.

self.persons is my data source

    NSMutableArray *newPeople = [NSMutableArray new];

    NSArray *popular = [self fetchFewPopular];
    [newPeople addObjectsFromArray:popular];

    NSArray *randoms = [self fetchFewRandoms];
    [newPeople addObjectsFromArray:randoms];

    NSArray *reminders = [self fetchFewRandoms];
    [newPeople addObjectsFromArray:reminders];

    [self shuffleArray:newPeople];

    [self.tableView beginUpdates];

    NSMutableArray *insertingRows = [NSMutableArray new];
    [self.persons addObjectsFromArray:newPeople];

    for (Person *newPerson in newPeople) {
        [insertingRows addObject:[NSIndexPath indexPathForRow:[self.persons indexOfObject:newPerson] inSection:0]];
    }
    [self.tableView insertRowsAtIndexPaths:insertingRows withRowAnimation:UITableViewRowAnimationNone];
    [self.tableView endUpdates];
    for (Person*person in newPeople) {
        [self.personObjectIDS addObject:person.objectID];
    }

The Stack trace of the Exception:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 3 beyond bounds [0 ..

2]' *** First throw call stack: ( 0 CoreFoundation __exceptionPreprocess + 165 1 libobjc.A.dylib
objc_exception_throw + 45 2 CoreFoundation
-[__NSArrayM objectAtIndex:] + 227 3 UIKit
-[_UITableViewUpdateSupport(Private) _setupAnimationsForExistingVisibleCells] + 296 4 UIKit -[_UITableViewUpdateSupport _setupAnimations] + 151 5 UIKit
-[UITableView _updateWithItems:updateSupport:] + 1812 6 UIKit -[UITableView _endCellAnimationsWithContext:] + 11935 7 Touchiq 0x00


Solution

  • It's not a good idea to add or remove rows in tableView:cellForRowAtIndexPath:. That's because this method is called by the table view when it is being updated / reloaded. So when you trigger another update in the middle of an ongoing one, weird things might happen.

    A common practice is to use the method tableView:willDisplayCell:forRowAtIndexPath: to add new rows when the last cell is going to be displayed.

    Or alternatively, use scrollViewDidScroll method (from UIScrollViewDelegate) because UITableView is a subclass of UIScrollView. Popular SVPullToRefresh + SVInfiniteScrolling library uses this approach.