2009-11-21 109 views
1

这里移动行时是个例外:崩溃中的UITableView

Serious application error. Exception was caught during 
Core Data change processing: *** -[NSCFArray removeObjectAtIndex:]: 
index (0) beyond bounds (0) with userInfo (null) 

下面是相关代码:

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath 
{ 
    NSMutableArray *array = [[fetchedResultsController fetchedObjects] mutableCopy]; 

    id objectToMove = [[array objectAtIndex:fromIndexPath.row] retain]; 
    [array removeObjectAtIndex:fromIndexPath.row]; 
    [array insertObject:objectToMove atIndex:toIndexPath.row]; 
    [objectToMove release]; 

    for (int i=0; i<[array count]; i++) { 
     [(NSManagedObject *)[array objectAtIndex:i] setValue:[NSNumber numberWithInt:i] forKey:JKChecklistRow]; 
    } 
    [array release]; 
} 

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

- (void)controller:(NSFetchedResultsController *)controller 
    didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath *)indexPath 
    forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath *)newIndexPath 
{ 
    UITableView *tableView = self.tableView; 

    switch(type) { 
     case NSFetchedResultsChangeMove: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      // Reloading the section inserts a new row and ensures that titles are updated appropriately. 
      [tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 
} 

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

我有一个怀疑,这次金融危机是与核心数据商店与未保存的上下文不同步。如果我在-tableView:moveRowAtIndexPath:fromIndexPath:toIndexPath:方法中保存上下文,程序崩溃得更快,但我还是无法弄清楚为什么。

回答

1

我想通了。其实,Jeff LaMarche想通了。

的代码救了我的位:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    // In the simplest, most efficient, case, reload the table view. 
    if (!self.tableView.editing) 
     [self.tableView reloadData]; 
} 

由于我是在表视图自己周围移动这些行,这个视图已经反映了变化。当我更新数据源时,我的委托人会尝试重新排列已移动的行,导致崩溃。

+0

哦,快点。对此解决方案的一个警告是,显然,通过轻扫即可删除将表视图置于编辑模式。我的if语句导致数据现在不被重新加载。修复了另一个问题:-) – kubi 2009-12-06 12:48:08

1

如果在移动行时使用段,NSFetchedResultsController和表视图立即脱离同步。我想这是这个班的一个错误。所以这不是我的经验中未保存的情况。

其中一个问题是,在移动之后索引路径不是最新的,因此该路径上的行数不再正确,导致“索引超出范围”。假设你有一个(1,1)的索引并删除(1,1)处的行。索引点stil到(1,1),但是第1部分的内容不再是相同的等等等等。

只需让它看起来像 NSUInteger tableSectionCount = [self.tableView numberOfSections] ; NSUInteger frcSectionCount = [[controller sections] count]; NSLog(@“tableSectionCount:%d”,tableSectionCount); NSLog(@“frcSectionCount:%d”,frcSectionCount); ,你会看到。

此外,很难找到NSFRC使用NSFetchedResultsChangeMove或NSFetchedResultsChangeUpdate的所有情况。它强烈依赖于是否需要对行重新排序。 最后,你必须自己为每个特定的情况同步tabel view和NSFRC。最后我花了三天才弄明白。

这个很有帮助:http://iphonedevelopment.blogspot.com/2009/11/one-fix-to-nsfetchedresultscontroller.html。我已经向作者发送了更多发现,所以我猜想会有更新。

但是,关键是保持各部分是最新的。

祝你好运! Gerd

+0

感谢您的帮助!由于我在编辑模式下移动行时,我的解决方案比这更简单,但我相信Jeff的代码将在未来派上用场。 – kubi 2009-12-06 12:42:04