开发者

iPhone app crashing on [self.tableView endUpdates]

My table view shows a list of users. I'm having issues refreshing my table view after adding a user. I've tried different combinations of code and events and now the app is crashing on the endUpdates call. The app is modeled after the recipe app, so a user clicks the add button, and then a modal window appears asking for the users name. Then it goes to the edit screen, and then back to the list of users. At that point, the new user wasn't showing up. But if I navigated back to the main screen, and then back to the users screen, the user would appear.

Here's some of my code:

    - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    sectionInsertCount = 0;
    [self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
  [self.tableView endUpdates];

}

    - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
 switch(type) {

  case NSFetchedResultsChangeInsert:
            if (!((sectionIndex == 0) && ([self.tableView numberOfSections] == 1))) {
                [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                sectionInsertCount++;
            }

   break;
  case NSFetchedResultsChangeDelete:
            if (!((sectionIndex == 0) && ([self.tableView numberOfSections] == 1) )) {
                [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                sectionInsertCount--;
            }

   break;
        case NSFetchedResultsChangeMove:
            break;
        case NSFetchedResultsChangeUpdate: 
            break;
        default:
            break;
 }
}

    - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
 switch(type) {
  case NSFetchedResultsChangeInsert:
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
   break;
  case NSFetchedResultsChangeDelete:
   [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFa开发者_运维知识库de];
   break;
        case NSFetchedResultsChangeUpdate: {
            [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        }
  case NSFetchedResultsChangeMove:
            if (newIndexPath != nil) {

                NSUInteger tableSectionCount = [self.tableView numberOfSections];
                NSUInteger frcSectionCount = [[controller sections] count];
                if (frcSectionCount != tableSectionCount + sectionInsertCount)  {
                    [self.tableView insertSections:[NSIndexSet indexSetWithIndex:[newIndexPath section]] withRowAnimation:UITableViewRowAnimationNone];
                    sectionInsertCount++;
                }


                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [self.tableView insertRowsAtIndexPaths: [NSArray arrayWithObject:newIndexPath]
                                     withRowAnimation: UITableViewRowAnimationRight];

    runEndUpdates = NO;

            }
            else {
                [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[indexPath section]] withRowAnimation:UITableViewRowAnimationFade];
            }
   break;
        default:
   break;
 }
}

I'm almost at a breaking point with this. CoreData has been the most frustrating part of app development. Should I just switch to SQL Lite? Or will I still have the same issues?

Thanks!


In my experience, it must have some rows or sections inserted or removed between beginUpdated and endUpdated. If no rows or sections inserted or removed between beginUpdated and endUpdated, it will crash.

And, if the section number and row number are not correct, it will crash too. So, it needs coding very carefully.


Today I had the very same issue.

The problem was in my source code - one of UITableViewDataSource functions used invalid object (not CoreData object, simple array, which I forgot to retain), this caused crash. Unfortunately this was not clear from the call stack, no message was provided in the console.

So the reason might be in your implementation of UITableViewDataSource protocol.


I was seeing a crash in the same spot, but for a different reason. I would also see this weird behavior where the table view scrolling would slow to a crawl, and basically become unresponsive. The reason behind this ended up being kind of neat and interesting so I figured I'd share it.

My table view has a bunch of events sorted by date. Events are queried from a web API 50 at a time. Every time a new query is made, the fetched results update and new cells get animated in. Early on I noticed a lot of strange shifting when new rows would get added, but it just seemed like something to optimize later.

Events in the app can be saved and the table view has a way to filter between all events and saved events. One time I was just tapping the filter to switch back and forth between all events and saved events, and I noticed that within a particular day when I switched back to the all events view they would be rearranged.

Oh duh, I also need a descriptor for start time. That's something that will make the app nicer to use.

OH DUH! I bet this is why it's crashing too! Since every update was basically causing every existing row to be moved to a new spot, plus adding additional rows, I must have just been hitting some crash bug in the table view controller. Now the scrolling problems are gone, and the crash is gone too.

Lesson learned: Make sure your fetched results controller has enough sort descriptors for the results to be determinant on reloads of the view.


Try to call [self.tableview reloaddata] inside controllerDidChangeContent.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜