带有 NSFetchResultController 的 CoreData:使用 fetchObjects 中的属性进行的无效更新
Posted
技术标签:
【中文标题】带有 NSFetchResultController 的 CoreData:使用 fetchObjects 中的属性进行的无效更新【英文标题】:CoreData with NSFetchResultController :Invalid update with with a property in fetchObjects 【发布时间】:2016-01-26 08:16:00 【问题描述】:我有一个 Xcode 报告的严重问题:
1.我有一个 NSFetchResultsController
var fetchedResultsController: NSFetchedResultsController
if _fetchedResultsController != nil
return _fetchedResultsController!
let fetchRequest = NSFetchRequest()
// Edit the entity name as appropriate.
let entity = NSEntityDescription.entityForName("Choice", inManagedObjectContext: NSManagedObjectContext.MR_defaultContext())
fetchRequest.entity = entity
// Set the batch size to a suitable number.
fetchRequest.fetchBatchSize = 10
// Edit the sort key as appropriate.
let sortDescriptor = NSSortDescriptor(key: "id", ascending: false)
let sortDescriptors = [sortDescriptor]
fetchRequest.sortDescriptors = sortDescriptors
//NSPredicate
let predicate = NSPredicate(format: "decision.id = %@", decision.id!)
fetchRequest.predicate = predicate
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: NSManagedObjectContext.MR_defaultContext(), sectionNameKeyPath: nil, cacheName: nil)
aFetchedResultsController.delegate = self
_fetchedResultsController = aFetchedResultsController
do
try _fetchedResultsController?.performFetch()
catch let error as NSError
print(error)
return _fetchedResultsController!
2。我有一个按钮做添加动作:
@IBAction func didTouchAddChoiceButton(sender: UIButton)
let choice = Choice.MR_createEntity() as! Choice
choice.id = GDUtils.CMUUID()
choice.decision = decision
NSManagedObjectContext.MR_defaultContext().MR_saveToPersistentStoreAndWait()
3.添加此实体后。我有一个控制器来处理像这样更新 tableView
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?)
switch(type)
case .Insert:
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Top)
case .Delete:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
case .Update:
tableView.cellForRowAtIndexPath(indexPath!)
case .Move:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Left)
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
4.但是问题发生了:每次我尝试从 fetchedObjects 更改实体的属性时:
let chosenChoice = fetchedResultsController.objectAtIndexPath(currentIndextPath!) as! Choice
chosenChoice.name = tableCell.choiceName.text
我收到了这条消息:
CoreData:错误:严重的应用程序错误。在调用 -controllerDidChangeContent: 期间,从 NSFetchedResultsController 的委托中捕获了异常。无效更新:第 0 节中的行数无效。更新后现有节中包含的行数 (1) 必须等于更新前该节中包含的行数 (1),加上或减去数字从该部分插入或删除的行数(1 插入,0 删除)加上或减去移入或移出该部分的行数(0 移入,0 移出)。与 userInfo (null)
谁能帮我弄清楚发生了什么?
【问题讨论】:
您收到此错误是因为在 fetchResultsController 的托管 objectContext 中没有添加或删除任何行。 【参考方案1】:在 ios8 上的 NSFetchedResultsController 中存在一个错误,其中 FRC 调用 .Insert 而不是 .Update。我解决了这个问题,当在 iOS8 上调用 .Insert 时,我正在完全重新加载表格。
case .Insert:
guard let newIndexPath = newIndexPath else return
// iOS8 bug when FRC calls insert instead of Update
if #available(iOS 9, *)
// insert item normally
else
// reload everything
【讨论】:
【参考方案2】:确保您分配给 NSFetchResultsController 的 managedOjectContext 与您创建新的 Choice NSManagedObject 的位置相同。
添加
在“case .Update”代码中为您提供 tableview 单元格。并且您需要更新 tableView 单元格数据以免出现该错误。至少改变/(假装改变)单元格中的某事。
cell = tableView.cellForRowAtIndexPath(indexPath!)
cell.choiceName.text = "empty"
【讨论】:
我使用 MagicalRecord,它总是分配给 MR_DefaultContext 请参阅上面回复的添加部分:我认为此错误是因为您在更新选项 managedObject 时没有更改表视图中的任何内容。它会向 nsfetchresultcontroller 抛出更新通知,但如果您不更改单元格,您可能会收到此错误。以上是关于带有 NSFetchResultController 的 CoreData:使用 fetchObjects 中的属性进行的无效更新的主要内容,如果未能解决你的问题,请参考以下文章
如何翻转正面带有标签而背面带有另一个标签的视图 - 参见图片
CakePHP 如何处理带有/不带有 'id' 字段的 HABTM 表?
带有 RecyclerView 的 DialogFragment 比带有 Recyclerview 的 Fragment 慢