我有一个名为ToDoItem
的实体。其中有三个属性:
@NSManaged var toDoString: String?
@NSManaged var creationDate: NSDate?
@NSManaged var isComplete: NSNumber?
我正在尝试创建NSFetchedResultsController
,根据isComplete
变量显示两个部分。我能成功地做到这一点:
lazy var fetchedResultsController: NSFetchedResultsController = {
let questionAnswerFetchRequest = NSFetchRequest(entityName: "ToDoItem")
let questionAnswerFetchSortDescriptor = NSSortDescriptor(key: "creationDate", ascending: false)
questionAnswerFetchRequest.sortDescriptors = [questionAnswerFetchSortDescriptor]
let frc = NSFetchedResultsController(
fetchRequest: questionAnswerFetchRequest,
managedObjectContext: (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext,
sectionNameKeyPath:"isComplete",
cacheName: nil)
frc.delegate = self
return frc
}()
我也实现了这样的删除方法:
//
// MARK: Fetched Results Controller Delegate Methods
//
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
func controller(controller: NSFetchedResultsController,
didChange sectionInfo: NSFetchedResultsSectionInfo,
atSectionIndex sectionIndex: Int,
for type: NSFetchedResultsChangeType) {
switch (type) {
case .Insert:
self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
break
case .Delete:
self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
break
default:
break
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch (type) {
case .Insert:
if let indexPath = newIndexPath {
tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
break;
case .Delete:
if let indexPath = indexPath {
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
break;
case .Update:
if let indexPath = indexPath {
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}
break;
case .Move:
if let indexPath = indexPath {
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
if let newIndexPath = newIndexPath {
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
}
break;
}
}
问题是,当我更新isComplete
属性时,我收到此错误:
CoreData:错误:严重的应用程序错误。抓住了一个例外 在调用期间来自NSFetchedResultsController的委托 -controllerDidChangeContent :.无效更新:无效的节数。表视图中包含的节数 更新(1)必须等于包含的部分数 更新前的表视图(0),加号或减号 插入或删除的部分(插入0,删除0)。用户信息 (空)
我理解这是什么,我只是不明白为什么它导致了这个错误。我根据文档实现了委托方法.....
我更新了我的NSFetchedResultsController
创建,为@ wain的答案添加了另一个sortDescriptor,如下所示:
lazy var fetchedResultsController: NSFetchedResultsController = {
let questionAnswerFetchRequest = NSFetchRequest(entityName: "ToDoItem")
let isCompleteSortDescriptor = NSSortDescriptor(key: "isComplete", ascending: false)
let creationDateSortDescriptor = NSSortDescriptor(key: "creationDate", ascending: false)
questionAnswerFetchRequest.sortDescriptors = [isCompleteSortDescriptor, creationDateSortDescriptor]
let frc = NSFetchedResultsController(
fetchRequest: questionAnswerFetchRequest,
managedObjectContext: (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext,
sectionNameKeyPath:"isComplete",
cacheName: nil)
frc.delegate = self
return frc
}()
我添加了一些断点,事实证明这个委托方法永远不会被调用:
func controller(controller: NSFetchedResultsController,
didChange sectionInfo: NSFetchedResultsSectionInfo,
atSectionIndex sectionIndex: Int,
for type: NSFetchedResultsChangeType) {
switch (type) {
case .Insert:
self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
break
case .Delete:
self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
break
default:
break
}
}
导致与上面发布的错误相同的错误。关于为什么永远不会被召唤的任何想法?
答案 0 :(得分:3)
您需要为isComplete
添加排序描述符。它应该是第一个排序描述符,然后是你的日期。
基本上,排序和部分需要兼容,而你的目前不是。