NSFetchedResultsController + UICollectionViewDiffableDataSource + CoreData - 如何区分整个 object?
NSFetchedResultsController + UICollectionViewDiffableDataSource + CoreData - How to diff on the entire object?
我正在尝试使用 iOS13 中内置的一些新差异 classes 以及 Core Data。我 运行 遇到的问题是 controllerdidChangeContentWith
没有按预期工作。它传递给我一个快照参考,这是对 a
的参考
NSDiffableDataSourceSnapshot<Section, NSManagedObjectID>
意思是我得到了一个列表,其中包含 sections/Object 个已更改的 ID。
这部分效果很好。但是当您在 collection 视图中进行比较时,问题就来了。在 WWDC 视频中他们愉快地称呼
dataSource.apply(snapshot, animatingDifferences: true)
一切都神奇地工作,但实际情况并非如此API。
在我最初的尝试中,我尝试了这个:
resolvedSnapshot.appendItems(snapshot.itemIdentifiersInSection(withIdentifier: section).map {
controller.managedObjectContext.object(with: [=13=] as! NSManagedObjectID) as! Activity
}, toSection: .all)
这适用于填充单元格,但如果单元格上的数据发生更改(即单元格标题),则永远不会重新加载特定单元格。我看了一下快照,看来问题只是我引用了这些 activity objects,所以它们都同时更新(意思是旧快照中的 activity等同于新快照中的那个,因此哈希值相等。)
我当前的解决方案是使用一个包含我所有 Activity class 变量的结构,但它与 CoreData 断开连接。所以我的数据源变成了:
var dataSource: UICollectionViewDiffableDataSource<Section, ActivityStruct>
这样快照实际上得到了两个不同的值,因为它有两个不同的 objects 可以比较。这行得通,但似乎远非优雅,这是我们打算如何使用它吗?或者它现在只是处于损坏状态? WWDC 视频似乎暗示它不应该需要所有这些额外的样板文件。
我 运行 遇到了同样的问题,我想我找到了有效的办法:
有两个类:UICollectionViewDiffableDataSource
和UICollectionViewDiffableDataSourceReference
据我所知,当您使用第一个时,您将所有权作为“真相来源”,因此您创建了一个充当数据源的对象。当您使用第二个(数据源引用)时,您将“真相来源”推迟到另一个数据源(在本例中为 CoreData)。
您可以使用与 ...DataSource
基本相同的方式实例化 ...DataSourceReference
:
dataSourceReference = UICollectionViewDiffableDataSourceReference(collectionView: collectionView, cellProvider: { (collectionView, indexPath, object) -> UICollectionViewCell? in
let identifier = <#cell identifier#>
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath)
<#cell configuration#>
return cell
})
然后当你实现NSFetchedResultsControllerDelegate
时,你可以使用下面的方法:
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference)
{
dataSourceReference.applySnapshot(snapshot, animatingDifferences: true)
}
我也看了 WWDC 视频,但没有看到这个引用。不得不犯一些错误才能到达这里。希望对你有用!
我正在尝试使用 iOS13 中内置的一些新差异 classes 以及 Core Data。我 运行 遇到的问题是 controllerdidChangeContentWith
没有按预期工作。它传递给我一个快照参考,这是对 a
NSDiffableDataSourceSnapshot<Section, NSManagedObjectID>
意思是我得到了一个列表,其中包含 sections/Object 个已更改的 ID。
这部分效果很好。但是当您在 collection 视图中进行比较时,问题就来了。在 WWDC 视频中他们愉快地称呼
dataSource.apply(snapshot, animatingDifferences: true)
一切都神奇地工作,但实际情况并非如此API。
在我最初的尝试中,我尝试了这个:
resolvedSnapshot.appendItems(snapshot.itemIdentifiersInSection(withIdentifier: section).map {
controller.managedObjectContext.object(with: [=13=] as! NSManagedObjectID) as! Activity
}, toSection: .all)
这适用于填充单元格,但如果单元格上的数据发生更改(即单元格标题),则永远不会重新加载特定单元格。我看了一下快照,看来问题只是我引用了这些 activity objects,所以它们都同时更新(意思是旧快照中的 activity等同于新快照中的那个,因此哈希值相等。)
我当前的解决方案是使用一个包含我所有 Activity class 变量的结构,但它与 CoreData 断开连接。所以我的数据源变成了:
var dataSource: UICollectionViewDiffableDataSource<Section, ActivityStruct>
这样快照实际上得到了两个不同的值,因为它有两个不同的 objects 可以比较。这行得通,但似乎远非优雅,这是我们打算如何使用它吗?或者它现在只是处于损坏状态? WWDC 视频似乎暗示它不应该需要所有这些额外的样板文件。
我 运行 遇到了同样的问题,我想我找到了有效的办法:
有两个类:UICollectionViewDiffableDataSource
和UICollectionViewDiffableDataSourceReference
据我所知,当您使用第一个时,您将所有权作为“真相来源”,因此您创建了一个充当数据源的对象。当您使用第二个(数据源引用)时,您将“真相来源”推迟到另一个数据源(在本例中为 CoreData)。
您可以使用与 ...DataSource
基本相同的方式实例化 ...DataSourceReference
:
dataSourceReference = UICollectionViewDiffableDataSourceReference(collectionView: collectionView, cellProvider: { (collectionView, indexPath, object) -> UICollectionViewCell? in
let identifier = <#cell identifier#>
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath)
<#cell configuration#>
return cell
})
然后当你实现NSFetchedResultsControllerDelegate
时,你可以使用下面的方法:
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference)
{
dataSourceReference.applySnapshot(snapshot, animatingDifferences: true)
}
我也看了 WWDC 视频,但没有看到这个引用。不得不犯一些错误才能到达这里。希望对你有用!