2009-11-21 105 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