应用相同模型数据的快照仍然会导致收集单元重新加载

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

我的订阅触发得太频繁,导致我的代码调用 snapshot.apply() 的次数超出了必要的范围。虽然我同意我应该努力避免这种情况,但所有单元格都会重新生成这一事实表明我从根本上以某种方式滥用了我的 UICollectionViewDiffableDataSource。

我检查了,唯一调用数据源的代码如下

typealias DataSource = UICollectionViewDiffableDataSource<Section, CellModel>
typealias Snapshot = NSDiffableDataSourceSnapshot<Section, CellModel>

func setupDataSource() -> DataSource {
    let dataSource = DataSource(
        collectionView: collectionView,
        cellProvider: { collectionView, indexPath, model ->
          UICollectionViewCell? in
          let cell = collectionView.dequeueReusableCell(
            withReuseIdentifier: "CollabPageCollectionViewCell",
            for: indexPath) as? CollabPageCollectionViewCell
          cell?.pageModel = model
          return cell
      })
    return dataSource
}
func callAfterUpdatingCollectionModels() {
    if memory.count == collectionPages.count {
        for i in 0..<memory.count {
            if memory[i] != collectionModels[i] {
                print("EQUATABLE FAIL AT \(i)")
            }
            if memory[i].hashValue != collectionModels[i].hashValue {
                print("EQUATABLE FAIL AT \(i)")
            }
        }
    } else {
        print("This print should only be seen once ")
    }
    memory = collectionModels
    guard self.collectionView.dataSource != nil else { return }

    var snapshot = Snapshot()
    snapshot.appendSections([.main])
    snapshot.appendItems(collectionModels)

    self.dataSource.apply(snapshot, animatingDifferences: true)
}
onOverZealousModelSubscription {
   // Rebuild collectionModels to be exactly the same thing it used to be
   callAfterUpdatingCollectionModels()
}

然后是这里的模型对象

class CellModel: Hashable, Equatable, ObservableObject  {
    static func == (lhs: CellModel, rhs: CellModel) -> Bool {
        return lhs.id == rhs.id && lhs.aspect == rhs.aspect && lhs.delegate === rhs.delegate && lhs.shouldBeHighlighted == rhs.shouldBeHighlighted
    }

    let id: UUID
    let aspect: CGFloat
    private(set) weak var delegate: CellModelDelegate?
    @Published var shouldBeHighlighted: Bool

    func hash(into hasher: inout Hasher) {
        id.hash(into: &hasher)
        aspect.hash(into: &hasher)
        shouldBeHighlighted.hash(into: &hasher)
    }
}

那么什么给出了呢?对我来说,我已经验证了所有模型对象的哈希值和计数是否相等。 dequeueReusableCell 的回溯验证其来自 self.dataSource.apply 但这些单元格仍然在尝试更新。

我确实创建了一个最小可重现的案例,但据我所知,没有好的方法可以在此处上传该项目。

uicollectionview diffabledatasource
1个回答
0
投票

过了一段时间就明白了。事情是这样的。因为实现 Equatable 和 Hashable 的 UIDiffableDataSource 的实现是无效的,即使文档没有这样建议。

使这个对象实现 NSObject 并向目标 c 公开 equatable 和 hashable 就可以了。此处的答案对此进行了更详细的说明。 https://stackoverflow.com/a/69994675/3833632

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