ios - NSFetchedResultsController 无法识别删除

标签 ios swift core-data nsfetchedresultscontroller

我有多个核心数据实体,全部同步到服务器。为了进行测试,我构建了一个函数,它将: 1.删​​除所有核心数据实体 2.调用API刷新所有数据

     // Next delete data in all entities (but not user)
    for entity in CoreDataStack.sharedInstance.allEntities() {
        if (entity != "User") {
            if (DataAccess.deleteExisting(entityName: entity, inMoc: self.operationMOC)) {
                print("Deleted OK: \(entity)")
            } else {
                print("ERROR deleting \(entity)")
            }
        }
    }

    ....

    // Save updates
    self.operationMOC.performAndWait {
        do {
            try self.operationMOC.save()
        } catch {
            fatalError("ERROR: Failed to save operation moc: \(error)")
        }
    }
    self.mainThreadMOC.performAndWait {
        do {
            try self.mainThreadMOC.save()
        } catch {
            fatalError("ERROR: Failed to save main moc: \(error)")
        }
    }

问题是控制我的 UI 的 NSFetchedResultsController 似乎无法识别删除,当“didChange”委托(delegate)方法触发更新时给出错误

error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (14) must be equal to the number of rows contained in that section before the update (7), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)

我已将刷新功能分成两部分,这样我就可以看到删除从未被识别,因此当更新触发并尝试 tableView.insertRows(at: ...) 时,UITableView 行太多。 我还尝试在我的主线程上直接更新 MOC - 不走运

我还放了一个观察者:

NotificationCenter.default.addObserver(self, selector: #selector(MessagesTab.dataChanged), name: NSNotification.Name.NSManagedObjectContextObjectsDidChange, object: self.mainThreadMOC)

它在删除和更新时完美触发,所以 Core Data 正在做它的工作。

因此,在我转储 NSFetchResults Controller 并使用通知滚动我自己之前,我的问题是有人知道我在这里做错了什么吗? (在代码或期望中) 在过去的一天里,我一直对此感到困惑,因此我们将不胜感激地收到任何建议。

我的 NSFetchedResultsControllerDelegate didChange 方法:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    print(">>>> FRC Change Fired")
    switch type {
    case .insert:
        tableView.insertRows(at: [newIndexPath!], with: .automatic)
    case .delete:
        tableView.deleteRows(at: [indexPath!], with: .automatic)
    case .update:
        let rowMessage = self.fetchedResultsController.object(at: indexPath!)
        if let cell = self.tableView.cellForRow(at: indexPath!) as? InterestsListCell {
            cell.configureWithData(rowMessage)
        }
    default:
        print("Was not a update, delete or insert")
    }
}

最佳答案

非常感谢@JonRose 此代码不会导致 FRC 触发

    // Delete all records for the entity
    func deleteExisting(entityName: String, inMoc moc: NSManagedObjectContext) -> Bool {
    do {
        let request = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: request)
        try moc.execute(deleteRequest)
        return true
    } catch {
        print("ERROR: deleting existing records - \(entityName)")
        return false
    }
}

随后我对此进行了研究,希望它能帮助其他人 - 参见 WWDC 2015 session on Core Data显示此幻灯片的位置:enter image description here 我尝试过使用 .refreshAll() 和 .mergeChages,但对我来说最简单的似乎是放弃我的 FRC 并使用 NSManagedObjectContextDidSave 通知

关于ios - NSFetchedResultsController 无法识别删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43610719/

相关文章:

ios - Swift - SPGooglePlacesAutocomplete - 如何处理它?

ios - 在日历中选择多个日期

swift - self.name = Swift 中的名称。我不明白为什么需要这些代码

ios - Firebase 云函数始终返回 Null

iPhone - 有什么方法可以查看实时应用程序的核心数据存储吗?

ios - CoreData - 使用 NSManagedObjects 填充 TableView 但只保存一个

javascript - HTML5 视频暂停时显示海报图像或暂停按钮?

iphone - 如何根据内容扩展 uilabel 高度?

ios - 找不到 Firebase 模块

Swift 2 - 核心数据 - 面向对象编程