When animating the deletion of all rows and hence the deletion of all sections that included all rows of a UITableView I am running into this error:
CRASH: attempt to delete row 2 from section 0, but there are only 0 sections before the update
In particular I have a singleton manager class that serves as the table view data source and delegate. I post an NSNotification to tell the table view to delete rows that should be deleted, and that NSNotification triggers the following method:
 dispatch_async(dispatch_get_main_queue(), ^{
            if ([[[Manager sharedManager] justDeletedIndices] count] > 0) {
                [mainTableView beginUpdates];
                NSMutableArray <NSIndexPath *> *pathsToDelete = [[Manager sharedManager] justDeletedIndices];
                [mainTableView deleteRowsAtIndexPaths:pathsToDelete withRowAnimation:UITableViewRowAnimationFade];
                [[Manager sharedManager] setJustDeletedIndices:[NSMutableArray new]];
                [mainTableView endUpdates];
            } else {
                [mainTableView reloadData];
            }
        });
The code for the method is in turn triggered by a method in Manager like so:
- (void) deleteMessagesForNotificationObjects: (NSArray <Object *> *) objects {
    // this is where the property that includes the NSIndexPath
    [self p_updatePathsToDeleteForDeletedObjects:objects];
    // this is the notification that should trigger the code above
    [[NSNotificationCenter defaultCenter] postNotificationName:@"RefreshTableView" object:self];
    // this is where I modify the underlying data structures that power
    // the table view's data source
    NSMutableArray *localObjects = [objects mutableCopy];
    for (Object *obj in localObjects) {
        [self deleteMessageWithToken:obj.token andUniqueID:nil andFireDate:obj.displayDate];
    }
    NSArray *allKeys = [self.displayDict allKeys];
    NSMutableArray <NSString *> *keysToDelete = [NSMutableArray new];
    for (NSString *key in allKeys) {
        NSMutableArray <Object *> *currentArr = self.displayDict[key];
        NSMutableArray <Object *> *objsToDelete = [NSMutableArray new];
        for (int i = 0; i < [localObjects count]; i ++) {
            if ([currentArr containsObject:localObjects[i]]) {
                [objsToDelete addObject:localObjects[i]];
            }
        }
        [currentArr removeObjectsInArray:objsToDelete];
        [localObjects removeObjectsInArray:objsToDelete];
        if ([currentArr count] < 1) {
            [keysToDelete addObject:key];
        }
    }
    [self.displayDict removeObjectsForKeys:keysToDelete];
    self.keyOrder = [[[self class] orderedKeysFromDict:self.displayDict] mutableCopy];
}
I am unclear as to what has to happen in what order. How do the commands indicating to a table view that it has to delete certain rows in an animated fashion (discussed here: Add/Delete UITableViewCell with animation?) relate to the ordering of actually modifying the underlying data source? In what order do I (1) animate row deletion and section deletion and (2) actually delete those rows and sections?