Core data 在UITableView中移动行时崩溃

Core data 在UITableView中移动行时崩溃,core-data,uitableview,Core Data,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 moveRowAtIndex

例外情况如下:

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];
}
-(void)tableView:(UITableView*)tableView移动rowatindexpath:(nsindepath*)从indepath到indepath:(nsindepath*)到indepath
{
NSMutableArray*数组=[[fetchedResultsController FetchedObject]mutableCopy];
id objectToMove=[[array objectAtIndex:fromIndexPath.row]retain];
[array removeObjectAtIndex:fromIndexPath.row];
[array insertObject:objectToMove atIndex:toIndexPath.row];
[目的性释放];

对于(int i=0;i如果在移动行时使用节,NSFetchedResultsController和表视图会立即停止同步。我猜这是此类中的一个错误。因此,这不是我经验中未保存的上下文

其中一个问题是,移动后索引路径不是最新的,因此该路径上的行数不再正确,这导致“索引超出边界”。假设您有一个到(1,1)的索引,并在(1,1)处删除该行。索引仍然指向(1,1),但第1节的内容不再相同等

只要用类似的东西让它对你可见 NSInteger tableSectionCount=[self.tableView numberOfSections]; NSU整数frcSectionCount=[[controller sections]count]; NSLog(@“表分区计数:%d”,表分区计数); NSLog(@“frcSectionCount:%d”,frcSectionCount); 你会看到的

此外,很难找到NSFRC使用NSFetchedResultsChangeMove或NSFetchedResultsChangeUpdate的所有情况。这在很大程度上取决于是否需要对行进行重新排序。 最后,你必须为每一个具体的案例自己同步tabel view和NSFRC。最后我花了三天的时间来解决这个问题

非常有用的是:。我已经向作者发送了更多的发现,所以我想会有更新

但同样重要的是:关键是让你自己的部分保持最新

祝你好运!
格尔德

我明白了。事实上,我明白了

救了我一命的代码:

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

由于我在表视图中移动了这些行,视图已经反映了更改。当我更新数据源时,我的代理会尝试重新排列已经移动的行,导致崩溃。

感谢帮助!由于我在编辑模式下移动行,我的解决方案比这简单,但我确信Jeff的代码将在将来派上用场。噢,很快。此解决方案的一个警告是,很明显,滑动到delete会将表视图置于编辑模式。My if语句会导致现在不重新加载数据。修复了一个问题,导致了另一个问题。:-)