I have a subscription that fires too often causing my code to call snapshot.apply() way more than is necessary. And while I agree I should work to avoid this the fact that all the cells regenerate suggests to me that I am fundamentally misusing my UICollectionViewDiffableDataSource in some way.
I checked and the only code doing calls to the data source is the following
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()
}
And then the model object here
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)
}
}
So what gives? To me I have verified the hashes and count of all model objects are equal. The backtrace of the dequeueReusableCell verifies its coming from the self.dataSource.apply yet STILL these cells are all trying to update.