从 SyncTable 拉取更新核心数据对象,而不是调用 NSFeatchedResults 委托方法
Updates to core data object from SyncTable pull, not calling NSFeatchedResults delegate methods
我正在使用 NSFetchedResultsController 使用来自 coredata 实体的数据跟踪和加载具有两个部分(基于可用的 true 或 false)的 UITableView。 Coredata 实体由 azure syncTable pull 方法填充。我从 VC 中的 ViewDidLoad() 方法调用 fetchedDataController?.performFetch()。
数据分为两部分-实体数据中section 1 available为false,section2- avaliable为true。
这是 NSFRC 初始化的代码片段:
lazy var fetchedDataController: NSFetchedResultsController<Product>? = {
let req = NSFetchRequest<NSFetchRequestResult>(entityName: "Product")
req.sortDescriptors = [NSSortDescriptor(key: "available", ascending: true), NSSortDescriptor(key: "createdAt", ascending: false)]
guard let dbContext = self.appDelegate?.managedObjectContext else { return nil }
let controller = NSFetchedResultsController(fetchRequest: req, managedObjectContext: dbContext, sectionNameKeyPath: "available", cacheName: nil) as? NSFetchedResultsController<Product>
controller?.delegate = self
return controller
}()
问题:
1. 即使实体行数据有更新,FRC 委托方法也不会自动触发。就像我在后端将 available 从 true 更改为 false 并做了一个 SyncTable.pull,我可以看到 coredata table 更新了最新数据(我打开了 .sql 文件并且能够看到数据)
- 为了克服变通方法,我每次拉取时都会调用 perform fetch,在这种情况下,当我向下滚动到第 2 部分时,应用程序因索引错误而崩溃,这意味着它不会更新 table 部分,并且行正确。
委托方法实现:
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.beginUpdates()
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.endUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
let sectionIndexSet = IndexSet(integer: sectionIndex)
switch type {
case .insert:
self.tableView.insertSections(sectionIndexSet, with: .fade)
case .update:
self.tableView.reloadSections(sectionIndexSet, with: .fade)
case .delete:
self.tableView.deleteSections(sectionIndexSet, with: .fade)
default: break
}
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
if let newIndex = newIndexPath {
self.tableView.insertRows(at: [newIndex], with: .fade)
}
case .update:
if let index = indexPath {
self.tableView.reloadRows(at: [index], with: .fade)
}
case .move:
if let index = indexPath {
self.tableView.deleteRows(at: [index], with: .fade)
if let newIndex = newIndexPath {
self.tableView.insertRows(at: [newIndex], with: .fade)
}
}
case .delete:
if let index = indexPath {
self.tableView.deleteRows(at: [index], with: .fade)
}
default: break
}
}
我深陷其中,不胜感激。
fetchedResultsController 监视特定上下文 - 而不是 sql 文件。如果您的应用程序中有多个上下文,则一个上下文的更改可能不会合并到另一个上下文中。因此,即使更新 sql 文件,上下文也不会更新。当您创建上下文时,请确保设置 viewContext
的 automaticallyMergesChangesFromParent
= true。
为 managedobjectcontext 保存添加观察者解决了这个问题:
NotificationCenter.default.addObserver(self, 选择器: #selector(refreshContent), 名称: NSNotification.Name.NSManagedObjectContextDidSave, 对象: nil)
func refreshContent(notif: 通知)
{
自己。 fetchedDataController?.managedObjectContext.mergeChanges(fromContextDidSave: notifn)
}
我正在使用 NSFetchedResultsController 使用来自 coredata 实体的数据跟踪和加载具有两个部分(基于可用的 true 或 false)的 UITableView。 Coredata 实体由 azure syncTable pull 方法填充。我从 VC 中的 ViewDidLoad() 方法调用 fetchedDataController?.performFetch()。 数据分为两部分-实体数据中section 1 available为false,section2- avaliable为true。
这是 NSFRC 初始化的代码片段:
lazy var fetchedDataController: NSFetchedResultsController<Product>? = {
let req = NSFetchRequest<NSFetchRequestResult>(entityName: "Product")
req.sortDescriptors = [NSSortDescriptor(key: "available", ascending: true), NSSortDescriptor(key: "createdAt", ascending: false)]
guard let dbContext = self.appDelegate?.managedObjectContext else { return nil }
let controller = NSFetchedResultsController(fetchRequest: req, managedObjectContext: dbContext, sectionNameKeyPath: "available", cacheName: nil) as? NSFetchedResultsController<Product>
controller?.delegate = self
return controller
}()
问题: 1. 即使实体行数据有更新,FRC 委托方法也不会自动触发。就像我在后端将 available 从 true 更改为 false 并做了一个 SyncTable.pull,我可以看到 coredata table 更新了最新数据(我打开了 .sql 文件并且能够看到数据)
- 为了克服变通方法,我每次拉取时都会调用 perform fetch,在这种情况下,当我向下滚动到第 2 部分时,应用程序因索引错误而崩溃,这意味着它不会更新 table 部分,并且行正确。
委托方法实现:
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.beginUpdates()
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.endUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
let sectionIndexSet = IndexSet(integer: sectionIndex)
switch type {
case .insert:
self.tableView.insertSections(sectionIndexSet, with: .fade)
case .update:
self.tableView.reloadSections(sectionIndexSet, with: .fade)
case .delete:
self.tableView.deleteSections(sectionIndexSet, with: .fade)
default: break
}
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
if let newIndex = newIndexPath {
self.tableView.insertRows(at: [newIndex], with: .fade)
}
case .update:
if let index = indexPath {
self.tableView.reloadRows(at: [index], with: .fade)
}
case .move:
if let index = indexPath {
self.tableView.deleteRows(at: [index], with: .fade)
if let newIndex = newIndexPath {
self.tableView.insertRows(at: [newIndex], with: .fade)
}
}
case .delete:
if let index = indexPath {
self.tableView.deleteRows(at: [index], with: .fade)
}
default: break
}
}
我深陷其中,不胜感激。
fetchedResultsController 监视特定上下文 - 而不是 sql 文件。如果您的应用程序中有多个上下文,则一个上下文的更改可能不会合并到另一个上下文中。因此,即使更新 sql 文件,上下文也不会更新。当您创建上下文时,请确保设置 viewContext
的 automaticallyMergesChangesFromParent
= true。
为 managedobjectcontext 保存添加观察者解决了这个问题:
NotificationCenter.default.addObserver(self, 选择器: #selector(refreshContent), 名称: NSNotification.Name.NSManagedObjectContextDidSave, 对象: nil)
func refreshContent(notif: 通知) { 自己。 fetchedDataController?.managedObjectContext.mergeChanges(fromContextDidSave: notifn)
}