我有一個標準的拆分視圖控制器,具有詳細視圖和表視圖。按詳細視圖中的按鈕可以使對象在表視圖的排序中更改其位置。這工作正常,只要結果訂購更改不會導致添加或刪除部分。即一個對象可以改變它在一個部分的順序或者從一個部分切換到另一個部分。這些訂購更改正常工作沒有問題。但是,如果對象試圖移動到尚不存在的部分,或者是最後一個要離開某個部分的對象(因此需要移除該部分),那麼應用程序會崩潰。「didChangeSection:」NSfetchedResultsController委託方法不被調用
NSFetchedResultsControllerDelegate有方法來處理在這些情況下應該調用的被添加和刪除的部分。但是這些委託方法由於某種原因沒有被調用。
有問題的代碼是樣板:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
NSLog(@"willChangeContent");
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
NSLog(@"didChangeSection");
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
NSLog(@"didChangeObject");
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
NSLog(@"didChangeContent");
[self.tableView endUpdates];
[detailViewController.reminderView update];
}
啓動應用程序,然後導致的最後一個對象留在下面的輸出部分結果:
2011-01-08 23:40:18.910 Reminders[54647:207] willChangeContent
2011-01-08 23:40:18.912 Reminders[54647:207] didChangeObject
2011-01-08 23:40:18.914 Reminders[54647:207] didChangeContent
2011-01-08 23:40:18.915 Reminders[54647:207] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1145.66/UITableView.m:825
2011-01-08 23:40:18.917 Reminders[54647:207] Serious application error. Exception was caught during Core Data change processing: Invalid update: invalid number of sections. The number of sections contained in the table view after the update (5) must be equal to the number of sections contained in the table view before the update (6), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted). with userInfo (null)
正如你所看到的,「willChangeContent」,「didChangeObject」(移動有問題的對象)和「didChangeContent」都被正確調用。基於蘋果的NSFetchedResultsControllerDelegate文檔「didChangeSection」應該在「didChangeObject」之前被調用,這將防止導致崩潰的異常。
所以我想問題是我如何確保didChangeSection被調用?
在此先感謝您的幫助!
我在我的項目中遇到了非常類似的問題。 didChangeSection似乎並不會在應該調用時調用。我爲sectionNameKeyPath使用「objectID.URIRepresentation」,因爲我希望每個對象都在它自己的部分中。我正在iPhone 5.1模擬器中測試。我的FRC根據值排序(增加到減少),所以如果一個對象的值改變,我的部分的順序也應該改變,但didChangeSection函數永遠不會被調用。你有什麼直覺爲什麼這可能會發生?謝謝。 – klyngbaek 2012-03-25 00:04:26
我也在爲此苦苦掙扎,首先爲sectionNameKeyPath指定nil。當所有的對象被刪除時,我返回0的tableView的數據源方法(fetchedObjects == 0),這打破了tableView的部分數。如果您需要觸發此委託方法,則應該指定某種類型的sectionNameKeyPath。現在看起來很明顯,只是認爲我會分享那些像我一樣木頭的人。 – Schoob 2012-09-04 11:05:37