是否可以从NSFetchedResultsController中获取最新快照 [英] Is it possible to source an up-to-date snapshot from an NSFetchedResultsController
问题描述
从iOS 13开始,保持 UITableView
与 NSFetchedResultsController
同步的最简单方法是
As of iOS 13, the easiest way to keep a UITableView
in sync with a NSFetchedResultsController
seems to be with snapshots.
无论何时ManagedObjectContext报告添加,删除或更新,NSFetchedResultsController都会向其委托人提供快照引用。使用快照( NSDiffableDataSourceSnapshot
)时,仅需要实现一种FRC委托方法: controller(_:didChangeContentWith:)
。为了使该委托方法起作用,必须将UITableViewDiffableDataSource和快照键入< String,NSManagedObjectID>
。
The NSFetchedResultsController vends a snapshot reference to its delegate whenever the managedObjectContext reports additions, deletions, or updates. When using snapshots (NSDiffableDataSourceSnapshot
), there is only one FRC delegate method that needs to be implemented: controller(_:didChangeContentWith:)
. In order to make that delegate method work, the UITableViewDiffableDataSource and the Snapshot has to be typed <String, NSManagedObjectID>
.
It 主要。
但是如果需要更新整个表怎么办?使用 tableView.reloadData()
或 frc.performFetch()
似乎是反模式。
But what if the entire table needs to be updated? Using tableView.reloadData()
or frc.performFetch()
seems anti-pattern.
编辑
我手动创建了一个快照,并在必要时调用apply。但是,由于我的快照基于NSFetchedResultsSectionInfo对象,因此似乎在复制FRC已有的内容:可散列的标题和可散列的NSManagedObjectIDs
I manually built a snapshot, and call apply when necessary. But since my snapshot is based on NSFetchedResultsSectionInfo objects, it seems like I'm duplicating what the FRC already has available: Hashable section titles, and Hashable NSManagedObjectIDs
推荐答案
对于我以前的(已删除)答案,我深表歉意。快照与Core Data上下文无关。
I apologize for my previous (deleted) answer. The snapshot is irrelevant in a Core Data context.
NSFetchedResultsController
与 Core Data
用于在保存 NSManagedObjectContext
时更新UI。
The purpose of NSFetchedResultsController
in conjunction with Core Data
is to update the UI when the NSManagedObjectContext
is saved.
能够控制动画的diffable数据源(要解决可笑的行为),必须子类化 UITableViewDiffableDataSource
并添加属性 animatingDifferences
。在子类中进一步使用 NSFetchedResultsControllerDelegate
(在视图控制器中为 not )。
To be able to control the animation of the diffable data source (to work around the ridiculous behavior) you have to subclass UITableViewDiffableDataSource
and add a property animatingDifferences
. Further adopt NSFetchedResultsControllerDelegate
in the subclass (not in the view controller).
class DiffableCoreDataSource: UITableViewDiffableDataSource<String,NSManagedObjectID> {
var animatingDifferences = false
}
extension DiffableCoreDataSource : NSFetchedResultsControllerDelegate
{
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) {
apply(snapshot as NSDiffableDataSourceSnapshot<String, NSManagedObjectID>, animatingDifferences: animatingDifferences)
animatingDifferences = true // set it to the default
}
}
在视图控制器中,将FRC的 delegate
设置为子类,并假设存在表示 DiffableCoreDataSource
In the view controller set the delegate
of the FRC to the subclass assuming there is a dataSource
property representing DiffableCoreDataSource
frc.delegate = dataSource
如果记录已更新,请设置 dataSource.animatingDifferences $ c $在保存上下文之前,将c>更改为
false
。
If a record is updated set dataSource.animatingDifferences
to false
right before saving the context.
要重新加载整个表视图,请调用 frc.p erformFetch()
。永远不要在表视图上调用 reloadData()
。
To reload the entire table view call frc.performFetch()
. Never call reloadData()
on the table view.
这篇关于是否可以从NSFetchedResultsController中获取最新快照的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!