0

尝试访问NSFetchedResultsController.

2013-11-10 15:15:06.568 Social[11503:70b] CoreData: error: Serious application error.  Exception was caught during Core Data change processing.  This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.  *** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds for empty array with userInfo (null)
2013-11-10 15:15:06.570 Social[11503:70b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds for empty array'

viewDidLoad

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.resultController = [DataEngine sharedInstance].postsFetchedResultController;
    self.resultController.delegate = self;
    [self.resultController performFetch:nil];

    [self.tableView reloadData];

    [[DataEngine sharedInstance] fetchInBackground];
}

结果控制器代表

#pragma mark - NSFetchedResultsControllerDelegate Methods -

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

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

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
    switch (type)
    {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertRowsAtIndexPaths:@[indexPath]
                                  withRowAnimation:UITableViewRowAnimationAutomatic];
            break;

        case NSFetchedResultsChangeUpdate:
            [self.tableView reloadRowsAtIndexPaths:@[indexPath]
                                  withRowAnimation:UITableViewRowAnimationAutomatic];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteRowsAtIndexPaths:@[indexPath]
                                  withRowAnimation:UITableViewRowAnimationAutomatic];
            break;

        case NSFetchedResultsChangeMove:
            [self.tableView moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
            break;

        default:
            break;
    }
}

表视图

#pragma mark - UITableView Delegate & Datasrouce -

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.resultController.fetchedObjects.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [self cellForRowAtIndexPath:indexPath];
}
4

2 回答 2

0

下面行崩溃的一个原因可能是您在使用 self.resultContrlller 重新调整表部分的行数之后更新它。确保如果您不断更新您的 self.resultContrlller 对象,那么您将复制它,然后用于您的表格绘图。

// This code does not prevent crash. Changing your regular code to modern objective-C way
Post *post = [self.resultContrlller fetchedObjects][indexPath.row];

当表重新加载自身时,数据源不应更改。您应该使用 fetchedObjects 的副本来加载表。因此,每次重新加载表格之前,请复制一份 [[self.resultContrlller fetchedObjects] 副本] 并将其用于表格绘制。然后,您的主要来源可以不断变化。在表重新加载完成复制后,如果数据发生更改,您可能需要再次重新加载它。当您的数据源更改速度快于表重新加载时,就会发生此类崩溃。

于 2013-11-10T23:17:05.483 回答
0

在我的 NSManagedObject 子类之一中,我有导致问题的以下代码。NSSets 在 NSManagedObejcts 上自动初始化,不需要初始化它们。

- (void)awakeFromFetch
{
    if (!self.comments)
        self.comments = [NSMutableSet set];

    if (!self.medias)
        self.medias = [NSMutableSet set];
}

另一个问题是,在插入 indexPath 为空时,我不得不改用 newIndexPath

case NSFetchedResultsChangeInsert:
    [self.tableView insertRowsAtIndexPaths:@[newIndexPath]
                          withRowAnimation:UITableViewRowAnimationAutomatic];
    break;
于 2013-11-11T02:20:54.213 回答