From 8f0d651f5fc2b2b0372c1409456da09cb59c8b4e Mon Sep 17 00:00:00 2001 From: Joseph Duffy Date: Tue, 3 Nov 2020 13:09:45 +0000 Subject: [PATCH 1/2] Potential fix for invalidation crashes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As mentioned in https://github.com/composed-swift/ComposedUI/issues/13 and https://github.com/composed-swift/ComposedUI/issues/8 there are some scenarios where the collection view’s data is out-of-sync with the data in composed. As mentioned in https://github.com/composed-swift/ComposedUI/issues/13 calling `layoutIfNeeded` can trigger the data to be in sync again. In this I have added it to `mappingWillBeginUpdating(_:)` which _appears_ to solve the problem. It might be needed in `replace(sectionProvider:)` (because `reloadData` is called) and/or `mappingDidInvalidate(_:)` (for the same reason) but I’m still investigating. --- Sources/ComposedUI/CollectionView/CollectionCoordinator.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/ComposedUI/CollectionView/CollectionCoordinator.swift b/Sources/ComposedUI/CollectionView/CollectionCoordinator.swift index 51376af..252b679 100644 --- a/Sources/ComposedUI/CollectionView/CollectionCoordinator.swift +++ b/Sources/ComposedUI/CollectionView/CollectionCoordinator.swift @@ -217,6 +217,7 @@ extension CollectionCoordinator: SectionProviderMappingDelegate { public func mappingWillBeginUpdating(_ mapping: SectionProviderMapping) { reset() defersUpdate = true + collectionView.layoutIfNeeded() } public func mappingDidEndUpdating(_ mapping: SectionProviderMapping) { From f14dd9f0e4d8d1644d17da13b837fcd3f1b0a731 Mon Sep 17 00:00:00 2001 From: Joseph Duffy Date: Tue, 3 Nov 2020 14:21:23 +0000 Subject: [PATCH 2/2] Comment why `layoutIsNeeded` is called --- .../ComposedUI/CollectionView/CollectionCoordinator.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Sources/ComposedUI/CollectionView/CollectionCoordinator.swift b/Sources/ComposedUI/CollectionView/CollectionCoordinator.swift index 252b679..a5f8faa 100644 --- a/Sources/ComposedUI/CollectionView/CollectionCoordinator.swift +++ b/Sources/ComposedUI/CollectionView/CollectionCoordinator.swift @@ -217,6 +217,13 @@ extension CollectionCoordinator: SectionProviderMappingDelegate { public func mappingWillBeginUpdating(_ mapping: SectionProviderMapping) { reset() defersUpdate = true + + // This is called here to ensure that the collection view's internal state is in-sync with the state of the + // data in hierarchy of sections. If this is not done it can cause various crashes when `performBatchUpdates` is called + // due to the collection view requesting data for sections that no longer exist, or crashes because the collection view is + // told to delete/insert from/into sections that it does not yet think exist. + // + // For more information on this see https://github.com/composed-swift/ComposedUI/pull/14 collectionView.layoutIfNeeded() }