NSFetchedResultsController + UICollectionViewDiffableDataSource + CoreData-如何区分整个对象?

问题描述 投票:1回答:1

我正在尝试使用iOS 13中内置的一些新的diffing类以及Core Data。我遇到的问题是controllerdidChangeContentWith无法正常工作。它给我传递了一个快照引用,它是对NSDiffableDataSourceSnapshot<Section, NSManagedObjectID>的引用,这意味着我可以获取已更改的节/对象ID的列表。

这部分效果很好。但是问题出在集合视图的差异上。在WWDC视频中,他们愉快地调用了dataSource.apply(snapshot, animatingDifferences: true),并且一切都神奇地工作了,但实际的API并非如此。

在我最初的尝试中,我尝试了这个:

resolvedSnapshot.appendItems(snapshot.itemIdentifiersInSection(withIdentifier: section).map {
     controller.managedObjectContext.object(with: $0 as! NSManagedObjectID) as! Activity
}, toSection: .all)

并且这适用于填充单元格,但是如果单元格上的数据发生更改(即单元格标题),则永远不会重新加载特定的单元格。我看了一下快照,看来问题很简单,我引用了这些活动对象,因此它们都同时更新(旧快照中的活动等同于新快照中的活动,因此哈希值相等。)

我当前的解决方案使用的结构包含我所有Activity类的变量,但是将其与CoreData断开连接。因此,我的数据源变为:var dataSource: UICollectionViewDiffableDataSource<Section, ActivityStruct>这样,快照实际上获得了两个不同的值,因为它有两个要比较的对象。这行得通,但似乎还远远不够优雅,这是我们本应使用的方式吗?还是现在只是处于破裂状态? WWDC视频似乎暗示它不需要所有这些额外的样板。

core-data uicollectionview nsfetchedresultscontroller
1个回答
0
投票

我遇到了同样的问题,我想我想出了什么可行的方法:

有两个类别:UICollectionViewDiffableDataSourceUICollectionViewDiffableDataSourceReference

据我所知,当您使用第一个时,您将所有权作为“真理的来源”,因此您创建了一个充当数据源的对象。当使用第二个(数据源引用)时,将“真理的源”推迟到另一个数据源(在本例中为CoreData)。

您将实例化...DataSourceReference的方式基本上与...DataSource相同:

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视频,也没有看到此内容。不得不犯一些错误才能到达这里。希望它对您有用!

© www.soinside.com 2019 - 2024. All rights reserved.