2010-10-12 21 views
1

我似乎遇到一個非常奇怪的問題,它只會在嘗試將新的NSManagedObject插入到新節中時發生。基本上我的部分是天和單個單元格與時間相關聯。當我將對象移動到當前沒有與當天關聯的另一個對象(錶行)的日子時,表需要創建一個新節並移動該行。而不是正確地發生我收到以下內容:嘗試將新表格行插入區段

嚴重的應用程序錯誤。在調用-controllerDidChangeContent:期間,NSFetchedResultsController的委託捕獲到異常。 * - [NSMutableArray的removeObjectAtIndex:]:指數1超出範圍[0 .. 0] USERINFO(空)

插入對於目前還沒有其他物體,每天一個新的對象似乎很好地工作。

這個問題似乎在這個代碼中的某個地方,但我似乎無法弄清楚它有什麼問題。 controller:didChangeSection:...似乎首先被插入和刪除,然後調用controller:didChangeObject:...與NSFetchedResultsChangeMove調用。所以順序是:

NSFetchedResultsChangeInsert(在didChangeSection) NSFetchedResultsChangeDelete(在didChangeSection) NSFetchedResultsChangeMove(在didChangeObject)

/** 
Delegate methods of NSFetchedResultsController to respond to additions, removals and so on. 
*/ 

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
// The fetch controller is about to start sending change notifications, so prepare the table view for updates. 
[self.plainTableView beginUpdates]; 
} 

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

switch(type) { 
    case NSFetchedResultsChangeInsert: 
     [tv insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    case NSFetchedResultsChangeDelete: 
     [tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    case NSFetchedResultsChangeUpdate: 
     [self configureCell:(UITableViewCell *)[tv cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
     break; 

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

- (void)controller:(NSFetchedResultsController *)controller 
    didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo 
      atIndex:(NSUInteger)sectionIndex 
    forChangeType:(NSFetchedResultsChangeType)type { 
    switch(type) { 
    case NSFetchedResultsChangeInsert: 
     [self.plainTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    case NSFetchedResultsChangeDelete: 
     [self.plainTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
} 
} 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
// The fetch controller has sent all current change notifications, so tell the table view to process all updates. 
[self.plainTableView endUpdates]; 
} 

我以爲這一切只是標準模板代碼雖然。有誰知道什麼可能是錯的?

實際上,它也會在嘗試向已存在的日期中插入新行時發生,但在插入新行/對象時尚未存在。

回答

1

我認爲你有一個概念性的問題這裏。

controller:didChange...方法應該被調用以響應由獲取結果控制器(FRC)檢測到的數據模型的變化。我很確定你的問題在於你在更改表格之前或者不更改底層數據。

段和行不是表的屬性,它們是由FRC構造的數據的屬性。如果您需要添加節,則需要先將其添加到數據中,然後讓FRC委派方法使表更新。該表反映了數據模型,而不是其他方式。

如果您不這樣做,FRC將報告錯誤的節數或行數,並導致表崩潰,並顯示您看到的錯誤。

+0

看了看似乎解決這個問題的代碼後,它看起來最初我沒有在NSFetchedResultsChangeMove中調用insertRowsAtIndexPaths。所以在NSFetchedResultsChangeMove行被刪除,但不重新插入其他地方。CoreDataBooks中的評論說:「重新加載該部分將插入一個新行並確保標題適當更新。」我想這意味着reloadSections用於插入行的調用,可能是在3.x SDK中。我確實注意到CoreDataBooks在某個時候更新了一些評論,說明它與4.x兼容 – Nimrod 2010-10-12 21:07:18

5

我似乎從最新版本CoreDataBooks的複製下面的代碼已經解決了這個問題:

case NSFetchedResultsChangeMove: 
     [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

這裏的代碼是之前:

case NSFetchedResultsChangeMove: 
     [tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     // Reloading the section inserts a new row and ensures that titles are updated appropriately. 
     [tv reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
+0

是的,那reloadSections線也崩潰了。 – RyeMAC3 2012-02-08 01:18:58