带有 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 中的属性进行的无效更新的主要内容,如果未能解决你的问题,请参考以下文章

带有和不带有聚合的 sql 查询

如何翻转正面带有标签而背面带有另一个标签的视图 - 参见图片

CakePHP 如何处理带有/不带有 'id' 字段的 HABTM 表?

带有滚动的 Div 和带有绝对位置的内容

带有 RecyclerView 的 DialogFragment 比带有 Recyclerview 的 Fragment 慢

访问控制允许带有和不带有 www 的来源