Commit graph

55 commits

Author SHA1 Message Date
Nolan O'Brien
d0d38c4a33 Fix up warnings to get Instagram code onto CompilerWarningLevel.HIGH
Summary:
many fixes for making IG `.HIGH` in warning level

https://fb.workplace.com/groups/iOSDevQA/posts/28237779439177303

Differential Revision: D72878674

fbshipit-source-id: 9f53bc19aa534c1c2252446faf06ef2c8dc20612
2025-04-14 15:23:41 -07:00
Nolan O'Brien
431ae719dc Fix up places to get Instagram hierarchy of code onto CompilerWarningLevel.HIGH
Summary:
many fixes for making IG `.HIGH` in warning level

https://fb.workplace.com/groups/iOSDevQA/posts/28237779439177303

Differential Revision: D72679686

fbshipit-source-id: 592b61515ca1480a0b37ebd35c88786f9e1b3469
2025-04-11 12:19:53 -07:00
Maxime Ollivier
7b78c95ed1 clean up ig_ios_listkit_fix_net_item_count
Summary: This was a killswitch to be safe, so lets clean it up.

Differential Revision: D67072925

fbshipit-source-id: ac54972030e7d53e7abd95025e45773aa3c5efc6
2024-12-12 04:02:03 -08:00
Maxime Ollivier
ab94446c63 add assert for iOS 18 cell dequeue exceptions
Summary:
iOS 18 has new exceptions, which can be a bit tough to debug. The common ones we see:
1. Cell dequeue outside of -cellForIndex
2. Dequeue being called more than once
3. Returning a cell that was not dequeued

Lets add an assert for each. #1 and #2 can actually assert on the problematic call, which will give a nice stack strace. #3 will still have a generic stack trace, but at least we'll see the section-controller.

Differential Revision: D62809660

fbshipit-source-id: 454c44598d4b21e09e6f66eb63c502b1b966a993
2024-09-17 07:11:55 -07:00
Maxime Ollivier
0c257795e4 fix crash when reloading the same cell index multiple times
Summary:
## Context
Merging multiple batch updates of the same section is inherently unsafe, because each block can mutate the underlaying list and lead to insert/deletes that operate on different before/after lists. The long term fix is to get rid of item level batch updates (insert/delete calls) and use diffing like for sections, but that's a much larger project.

Right now, we have a crash spiking because we're reloading the same cell multiple times. Each time `IGListDiff(...)` returns a pair of insert/delete for the same index (lets say 0). Once these updates are merge together, they look like this:
```
Item inserts = 0, 0
Item deletes = 0, 0
```
We dedupe deletes in `IGListBatchUpdateData`, but don't do anything for inserts, so it looks liket this:

```
Item inserts = 0, 0
Item deletes = 0
```

So we create an insert/delete unbalance and can crash. Tbh, not sure how this hasn't been a bigger issue in the past.

D21822502 tried to remove all duplicate inserts, but that caused other types of crashes, because multiple inserts are allowed.

## This diff

* Lets keep the net insert/delete count the same by keeping track of the number of deletes we remove and apply the same to inserts.
* Add some tests
* Add an experiment flag to kill this if needed to be safe. IG only: Note that I'm making the default true because the crash is happening pretty at start-up.

## Follow up

Over time, the batch update clean up logic was slowly added to multiple place (IGListBatchUpdateData, IGListAdapterUpdaterHelpers, IGListIndexPathResult), which is making it hard to follow. A first step would be to move it  in 1 or 2 places and avoid redundant logic (like getting unique deletes). However, the real fix is getting rid of batch updates all together.

Differential Revision: D61719884

fbshipit-source-id: eda7c264c8239a6a106dbe0256fe777b38fae335
2024-08-23 11:32:56 -07:00
Maxime Ollivier
5a93080f67 remove unsafe early exit on performDataSourceChange
Summary:
By making `-performUpdate` completely synchronous sometimes, it unearthed a bug with the early exit where multiple updates can happen at once. Specifically, the shortcut doesn't block updates from being started within `-didUpdateToObject`.

Lets test removing it, since it's happening in a pretty sensitive part of updates.

Differential Revision: D60773894

fbshipit-source-id: 721dffcb6d5353d12693fa873eb0f502bcdf4c02
2024-08-06 08:01:28 -07:00
Maxime Ollivier
420fa2794c increase coalesce window when collection-view is not visible
Summary: In case the collection-view is not visible, lets try batching more updates together to minimize the amount of off-screen work we do.

Differential Revision: D60691861

fbshipit-source-id: 154164fcd370e016c12bace60269c946a153c284
2024-08-06 08:01:28 -07:00
Maxime Ollivier
f429ec57af lower diffing priority if the collection-view is not visible
Summary: Lower QOS to give on-screen work priority.

Differential Revision: D60691856

fbshipit-source-id: 52b10e05cb999214ca6c6a8fe1cb3ce2dd847eb1
2024-08-06 08:01:28 -07:00
Maxime Ollivier
0056afb903 adaptive update coalescing
Summary:
Currently, we always call `dispatch_async` to coalesce updates, which slowing down the first update. Lets try a compromise where we don't delay the first update, but enforce a max update per time.

For example, lets say `minInterval = 10ms`,  `intervalIncrement = 10 ms`, and `maxInterval = 30 ms` ...
* At 0ms, the first `-queueUpdate` is called, which calls `_performUpdate` synchronously
* At 2ms, the update is done
* At 5ms, a second `-queueUpdate` is called. Since it's been less than 10ms, we wait 5ms and increase the next window to 20ms.
* At 10ms, the second `_performUpdate` is called.

So effectively, we speed up the first `-queueUpdate`, but enforce a max update per ms. I'm not convinced we really need the increment, but I want to see what happens IRL.

Differential Revision: D60691863

fbshipit-source-id: 85faf2dbc38f754976843fff63e6eada4972581e
2024-08-06 08:01:28 -07:00
Maxime Ollivier
adea343831 perform diffing on main thread if the items are low enough
Summary: Dispatching to a background thread and back to main can slow things down, since we might have to wait on the main thread to be available. For small diffs, we might be better off just doing it on main. If this does well, we can expend on it, like taking into account device type.

Differential Revision: D60691859

fbshipit-source-id: e1776e1e3bf493d99fcc6fe8af6d4c01d60da660
2024-08-06 08:01:28 -07:00
Maxime Ollivier
b714d4fe3b test higher QOS for diffing
Summary: `IGListKit` updates can block some interactions, so lets experiment with increasing the quality. Later, we'll decrease the quality if the `UICollectionView` is not visible.

Differential Revision: D60691858

fbshipit-source-id: 296715cac063eed4b2f4580950d5186f09893a39
2024-08-06 08:01:28 -07:00
Maxime Ollivier
604b67b6e6 adaptive diffing config
Summary:
* Create `IGListAdaptiveDiffingExperimentConfig` which will hold all the experiment params
* Fork `IGListPerformDiffWithData` between the regular vs adaptive diffing path. Might seem overkill right now, but `_queueForData` will get more complicated in the following diffs.

Differential Revision: D60691864

fbshipit-source-id: 6f9adc9bceecee704980ff968cd734c77be57f26
2024-08-06 08:01:28 -07:00
Maxime Ollivier
6c2cfcf6c7 clean up IGListExperimentKeepPointerToCollectionViewDataSource
Summary: QE launched and reduced crashes, so lets clean up

Differential Revision: D60184705

fbshipit-source-id: 574b0228e3efadf7bd3bd0677a4373a3b95888d1
2024-07-24 14:11:59 -07:00
Maxime Ollivier
d90909f1cd clean up IGListExperimentDisableAnimationOnUpdates
Summary: QE is done, so lets clean it up

Reviewed By: DimaVartanian

Differential Revision: D60184706

fbshipit-source-id: 3ece0452386fe1a3daad1f8958a65700431db36c
2024-07-24 14:11:59 -07:00
Harrison Huang
5c9d3a80c6 Boundary test of removing all IGListAdapter animation
Summary:
# Context

We've seen several experiments in which disabling standard-update animation yielded significant app-value wins. Overall there is a trend of moving towards snappier

- Reels grid disabled animation, led to vpvd wins
- Home feed disabled update animations -- led to Session and revenue wins

# This diff

From IGListAdapter+Common, create a kill switch to disable all animation. Potentially use this flag to dogfood and see where we have unnecessary animation.

Differential Revision: D54388375

fbshipit-source-id: a46c60944317db5deeceaac6d0baed71104d0c34
2024-03-02 00:50:49 -08:00
Maxime Ollivier
e3c5cfb59e keep pointer to self.collectionView.dataSource in IGListBatchUpdateTransaction
Summary:
## Issue
We're seeing crashes like this one:

```
Invalid batch updates detected: the number of sections and/or items returned by the data source before and after performing the batch updates are inconsistent with the updates.
Data source before updates = { 6 sections with item counts: [1, 0, 6, 8, 5, 7] }
Data source after updates = { 1 section with item counts: [0] }
Updates = [
]
```

I'm thinking the `IGListAdapter` gets deallocated during an update.
1. `1 section with item counts: [0]` is the default when the `self.collectionView.dataSource` is `nil`. I don't really see a way we'd return a single section with zero cells.
2. We're not seeing any of the additional crash information set by the `IGListAdapterUpdaterDelegate`, which would happen if `IGListAdapter` gets deallocated (it holds the strong pointer to the delegate).

## Fix

Lets keep a strong pointer within the scope of the function to make sure it sticks around. Theoretically, there could be a situation where the section-controller holds a strong pointer to the list-adapter in an update block, which gets released after it runs. This seems pretty unlikely, so lets test this fix to see if that's it.

Reviewed By: candance

Differential Revision: D52747014

fbshipit-source-id: 545aaa3deb90af85a011e716ac870659da42106f
2024-01-17 14:06:13 -08:00
Maxime Ollivier
b3a22ad554 clean up IGListExperimentSkipPerformUpdateIfPossible
Summary: This is probably not super safe, so lets kill it. If we want to know all the section and cell updates outside the update block, we need to make cells diffable, which is something we're considering.

Reviewed By: candance

Differential Revision: D52743451

fbshipit-source-id: fd8004876c452552931bf84ee73cd3ac15f3ba40
2024-01-17 14:06:13 -08:00
Maxime Ollivier
158beab01e clean up IGListExperimentSkipViewSectionControllerMap
Summary: This was added in 2020 (D24173911), lets kill it if we're not testing or shipping.

Reviewed By: candance

Differential Revision: D52743453

fbshipit-source-id: 9d02bd32fc31db36333e436c6420836e48cbbceb
2024-01-17 14:06:13 -08:00
Maxime Ollivier
99e24afbf8 clean up IGListExperimentFixCrashOnReloadObjects
Summary: Stability metrics look neutral, so lets ship! This was expected since we had a fix on the product side already. The IGListKit fix prevents it from happening in the first place.

Reviewed By: candance

Differential Revision: D52743455

fbshipit-source-id: e92b2a578b993cb228bbe245c3a1a5ac3bdfe5cf
2024-01-17 14:06:13 -08:00
Maxime Ollivier
5e79f8a319 add IGListExperimentThrowOnInconsistencyException
Summary:
Currently, we don't throw on `NSInternalInconsistencyException` as a temporary workaround, but there's a few issues with that:
1) `IGFailure` doesn't collect nearly as much information as exceptions, so it's difficult to debug. We could add more context to it, but feels like we should just fix the underlying issue instead, and remove the workaround.
2) If we throw in an animated update, all app animations break because `[UIView performWithoutAnimation:...]` doesn’t close properly.
3) Continuing to use the `UICollectionView` after it throws feels a bit risky IMO. There's no guarantee that it should work properly after that.

Lets reintroduce the exception slowly, fix each problem, and eventually remove the workaround.

In the future, we could do 2 other things:
1) Make `IGListExceptionDoctor` that can look at an exception's details and diagnose the issue, or at least provide more context.
2) Check if the updates make sense before telling the `UICollectionView`, so we can fallback to a `-reloadData`. This would shift the problem from a crash to a performance regression, so not ideal, but maybe less worse for production.

I'll add the experiment set-up in the next diffs.

Differential Revision: D50426255

fbshipit-source-id: 26e21d3dfcf4670ed07f397cf0d4decdda08eec5
2023-10-19 09:57:48 -07:00
Tim Oliver
20190830ec Fix IGWarnAssert macro to remove unneeded condition parameter
Summary:
I'm looking at updating IGKitKit's test suite for Xcode 15, but when I went to do a build, it failed at the `IGWarnAssert` macro. Turns out that because we set the condition in the macro to always return `(NO)`, there's no need to expose `frmt` to test for the condition.

This diff removes `frmt` from the define, allowing the tests to build again.

Reviewed By: fabiomassimo

Differential Revision:
D49628618

Privacy Context Container: L1203725

fbshipit-source-id: b0456a149bf5be96c8401a21866880ccd72ebbcb
2023-09-26 08:22:26 -07:00
Krys Jurgowski
050cd8e670 Downgrade IGListKit assertion
Summary: This assertion has been firing for at least the [last 3 months](https://fburl.com/scuba/errorreporting_instagram_ios_assertions/vfxo4h2g) and we have shipped the app anyways so it is definitely not launch blocking.

Reviewed By: fabiomassimo

Differential Revision: D49281317

fbshipit-source-id: d525f88fe676e813b8413a2e0f21b6b12728b359
2023-09-15 12:20:12 -07:00
Maxime Ollivier
cd3f84f227 fix crash when calling reloadObjects during an update
Summary:
Follow up to D47263265

## What's happening
We're calling `listAdapter.reloadObjects(...)` in the middle of the IGListKit's internal data update, so it's using the new section index path, instead of the old one. So we're going from a list of 2, insert at 0, and try to reload index 1, then we crash (it'll try to update index 2, which doesn't exist in the old array)

## Fix
Just like for `[IGListAdapter performBatchAnimated:updates:completion:]`, lets use the old index. To get this working, lets ask the updater if we're in an update, rather than `IGListAdapter` try to keep track of it.

Sorry the diff is a bit long, but in case this feels reasonable to pick, I might

Differential Revision: D47281472

fbshipit-source-id: 193153cfc15c87084b67f58c50e921db459d6800
2023-07-07 11:36:50 -07:00
Fabio Milano
dffcd4d0c8 Added new assertion level in IGListKit
Summary: Added new level of assertions for failures.

Differential Revision: D46029469

fbshipit-source-id: d8bd7ff41a19c15967e198c22aa5dc7b43972800
2023-05-19 13:40:51 -07:00
ke.xu
164f39c4d4 Fix unsigned integer overflow (#1299)
Summary:
## Changes in this pull request

Issue fixed: #

### Checklist

- [ ] All tests pass. Demo project builds and runs.
- [ ] I added tests, an experiment, or detailed why my change isn't tested.
- [ ] I added an entry to the `CHANGELOG.md` for any breaking changes, enhancements, or bug fixes.
- [ ] I have reviewed the [contributing guide](https://github.com/Instagram/IGListKit/blob/master/.github/CONTRIBUTING.md)
Pull Request resolved: https://github.com/Instagram/IGListKit/pull/1299

Reviewed By: m3rlin45

Differential Revision: D18703628

Pulled By: TimOliver

fbshipit-source-id: d347ed9c59c62ccdb73bd3abd14e289b7c06f3f6
2023-05-02 02:23:55 -07:00
Tim Oliver
f92b9339ee Standarize the copyright notice in all source files
Summary:
The standardized Meta copyright notice is "Copyright (c) Meta Platforms, Inc. and affiliates." and not "Copyright (c) Meta Platforms, Inc. and its affiliates." (Dropping the "its")

This diff updates the copyright notice in each source file to the correct this.

Reviewed By: willbailey

Differential Revision: D44737667

fbshipit-source-id: 643bf36df76723e70d9d826c53cf8f29b8a0c8cc
2023-04-06 02:44:16 -07:00
Tim Oliver
a1b9c2ddb3 Updated corporate branding in IGListKit source files
Summary:
A quick push to fix something I noticed while studying how IGListKit works. This simply replaces "Facebook, Inc" with "Meta Platforms, Inc" in all of the source files where the company copyright notice is posted. This should help bring our external facing projects more in line with our new corporate branding.

There's still a lot more references to "Facebook" as a company in the library (especially around linking to other Meta sponsored open source libraries), but this might need additional scrutiny and review on a case-by-case basis, so let's handle those ones separately.

Reviewed By: lorixx

Differential Revision: D41207363

fbshipit-source-id: 57cdbf5eb1023b41a5f32c0c05e01628686a19fe
2022-11-15 21:47:29 -08:00
Krys Jurgowski
2414d3cca5 Downgrade IGListAdapter assert
Summary:
Chatted with maxolls about this assertion - it fires when a user of IGListKit accidentally implements a UICV layout (which IGListKit will ignore). Definitely not ideal, but not a launch blocking issue so demoting this assert to a warning.

It's currently the second highest firing mustfix in alpha 239.
https://fburl.com/scuba/errorreporting_instagram_ios_assertions/yap7opjy

Reviewed By: maxolls

Differential Revision: D36983661

fbshipit-source-id: 00497637cffea7553495c837bec267acca7cd3d8
2022-06-09 09:06:29 -07:00
3a4oT
a1036e06e3 SPM number10 (#1487)
Summary:
## Changes in this pull request

 A better version of https://github.com/Instagram/IGListKit/issues/1465 =)

- SPM support with script-based generations.

- added macOS Catalyst support

 ### Generate SPM layout

1. From **project's root** run:

   `bash scripts/generate_spm_sources_layout.sh`

  2. Commit Changes

 Repeat those steps each time you delete/add the project's files. **Make sure** to have this CI step which will check that `generate_spm_sources_layout.sh` is not broken.

Issue fixed: https://github.com/Instagram/IGListKit/issues/1368 #1406

### Checklist

- [ ] All tests pass. Demo project builds and runs.
- [ ] I added tests, an experiment, or detailed why my change isn't tested.
- [ ] I added an entry to the `CHANGELOG.md` for any breaking changes, enhancements, or bug fixes.
- [ ] I have reviewed the [contributing guide](https://github.com/Instagram/IGListKit/blob/master/.github/CONTRIBUTING.md)

Pull Request resolved: https://github.com/Instagram/IGListKit/pull/1487

Reviewed By: DimaVartanian, candance

Differential Revision: D30428297

Pulled By: lorixx

fbshipit-source-id: 655291ff03445dec9b0b8cd97916f0c88207e9a7
2021-08-31 19:28:37 -07:00
Daniel Rodríguez
60bdc2edab Header compatibility with Mac Catalyst.
Summary:
In T97824645 a test that was failing for other reason was fixed and started
failing because it could not compile IGListKit.

The problem is that IGListKit was not prepared to be compiled for Mac Catalyst
since it was only testing for iOS platforms to include UIKit. These changes
modify the header to work in Mac Catalyst.

Differential Revision: D30410680

fbshipit-source-id: f886826b9c485acfb039a9e681afd85f9186c344
2021-08-19 16:56:47 -07:00
Zhisheng Huang
f4de8caff1 Remove UIKit dependencies in IGListDiffKit code
Summary:
This was accidentally introduced in D25334717 (9cb16b0f31), at the time I didn't pay close attention to the impact there. The diff actually broke the CI for IGListKit in open source community since IGListDiffKit was meant to be compatible in both MacOS and iOS.

The right approach is to rely on the IGListCompatibility.h to resolve the linked code here.

Reviewed By: rzito

Differential Revision: D30344334

fbshipit-source-id: 842ca560a1bfe6d54e7d90466575e4ed35cd9b87
2021-08-16 11:49:28 -07:00
Maxime Ollivier
9a11f6b55f graduate IGListExperimentBackgroundDiffing to a property
Summary:
`IGListExperimentBackgroundDiffing` has been running on Instagram for a couple months now, and we're seeing nice scroll performance improvements (less frame drops) without increasing crashes. Lets move the experiment to a real property!

Should it be enabled by default?
   * I'm leaning toward no, but I could be convinced otherwise. This optimization is good for large/complex applications with lots of diffing, but I'm not sure the more common apps would need it initially. It does make updates more complicated and the order of operation will be a bit different. For example, we've seen some places call `-performUpdatesAnimated` and almost immediately expect the `IGListAdapter` data to be updated, leading to missing views. This issue can still happen without background diffing, but less often.

Reviewed By: joetam

Differential Revision: D25884786

fbshipit-source-id: 3c8755a774f63868b7dfbc8e7a2e5c012a9e7e27
2021-01-21 19:58:49 -08:00
Maxime Ollivier
247e7cac65 ship the new updater
Summary:
It's time to ship the new updater! `IGListExperimentalAdapterUpdater` has been running on Instagram for a couple months with better performance and stability. In this diff, we're renaming `IGListExperimentalAdapterUpdater` (and related classes) to `IGListAdapterUpdater`.

Here's a recap:

## Stability

* `[IGListAdapter setDataSource]` isn't safe
  * We're changing the underlying data without telling the `UICollectionView`.
  * Fix: Lets invalidate the `UICollectionView` data by changing its dataSource.
* `[IGListAdapter setCollectionView]` isn't safe
  * This is synchronous, but we might have pending or on-going updates. The `UICollectionView` might get synced before the pending update actually start executing, so the diff results will be off.
  * Fix: Lets wrap updates in a transaction that can be cancelled.
* Returning a nil `IGListSectionController` from `IGListAdapterDataSource` could crash
  * The `IGListAdapterUpdater` will still perform the diffing assuming that all the objects will have a section, which isn't the case.
  * Fix: Lets generate the `IGListSectionController` before the diffing.
* Other improvements
  * Lets ask for the `fromObject` just before diffing, instead of asking when scheduling the update.
  * If the `UICollectionView` section count doesn't match `fromObject`, lets fallback to a reload.

## Performance

* Re-test background diffing
  * `IGListExperimentBackgroundDiffing` and coalescing updates wasn't safe because of the issues mentioned above. The longer we wait, the more likely we'll end up in a race condition. Lets try re-testing with the stability improvements.
* Unblocks background layout calculation
  * This is a larger project, but these improvements are required to make background work safe.
* Only create the `backgroundView` if needed (although this doesn't really require the new updater)

## Other

* Transactions
  * `IGListAdapterUpdater` is the workhorse of `IGListKit` and has become a bit hard to follow over the years. We want to break it apart into simpler, more manageable parts.
* Avoid blocks
  * There's a lot of blocks flying around, making crash logs hard to read. Lets try to use methods/functions where possible.

Reviewed By: Haud, lorixx

Differential Revision: D25884782

fbshipit-source-id: 1357fa23513a239051d5b1766823effa3199f656
2021-01-21 19:58:47 -08:00
Maxime Ollivier
329a4d300d ship IGListExperimentSectionCountValidation
Summary: This makes sure the `UICollectionView` section count matches what we expect before applying a diff results, if not, we fallback to a `reloadData`. This doesn't decrease the crash rate significantly, but it's nice to have a last line of defense. We do tradeoff crashes for performance issues, but it's better that an app works at all and we'll see the issue via asserts.

Reviewed By: lorixx

Differential Revision: D25884778

fbshipit-source-id: 5011d0907ce0f971ea3a0bf95c1549d52f615982
2021-01-21 19:58:47 -08:00
Maxime Ollivier
c0cf10d84c ship IGListExperimentArrayAndSetOptimization
Summary: This experiment shows a slight decrease in frame-drops on features that have more expensive hashing, so lets ship!

Reviewed By: lorixx

Differential Revision: D25884785

fbshipit-source-id: a5e33abe6f129166ab9b75de80636db801599b74
2021-01-21 19:58:46 -08:00
Richard Zito
9cb16b0f31 Import UIKit for NSIndexPath usage
Summary: `NSIndexPath` is in UIKit, so we should be importing its header.

Reviewed By: lorixx

Differential Revision: D25334717

fbshipit-source-id: 5a134a0ddbe88fddb33adfa182d7aaf437bc47d0
2020-12-04 10:55:46 -08:00
Zhisheng Huang
6311bbcfb4 Fix the visibleObjects inconsistency assertion
Summary:
Another source-of-truth inconsistency issue.

I kept getting this assertion T65423827 task.
It turned out the the root cause is that we use the `_viewSectionControllerMap` to keep track of the mapping between view and section controller.

Which is dangerous.
Because the UICV's source of truth is the `sectionMap`, now we are adding another source of truth between view <-> sectionController to be `_viewSectionControllerMap`, this is just waiting for bugs to happen.

We should always refers to sectionMap as the source of truth for everything here: since we can get the section index, we can replace all the `-sectionControllerForView` to use `-sectionControllerForSection:` instead, which is safer.

Multiple source of truth is the bug for this unexpected assertion.

Once we can cleanup this, then we dont need to use that weird: `- (void)mapView:(UICollectionReusableView *)view toSectionController:(IGListSectionController *)sectionController` API which we might forget to map, that can cause bug.

Reviewed By: elfredpagan

Differential Revision: D24173911

fbshipit-source-id: 6138cafc0b382fc569d17b14b13a6b50d85d342d
2020-10-17 02:05:24 -07:00
Maxime Ollivier
0693ca6be5 skip performBatchUpdates if possible
Summary: We don't actually need to call `[UICollectionVew performBatchUpdates ...]` if we don't have changes.

Reviewed By: patters

Differential Revision: D23386181

fbshipit-source-id: 469a22a35b9ead5181e95f36a8bc59ba36373bbe
2020-09-08 09:11:12 -07:00
Maxime Ollivier
fc8c4ba640 validate the section count before a performBatchUpdate
Summary:
We're seeing some crashes where the `UICollectionView`'s section count doesn't match the `fromObjets`. Ideally that shouldn't happen, but in case it does, lets fallback to a `reloadData` instead of crashing. Lets `IGFailAssert()` to keep an eye on it.

EDIT: Turns out `UICollectionView` will sometimes already do that for item-level inconsistencies! Example error message:
>  The number of items contained in an existing section after the update (9) must be equal to the number of items contained in that section before the update (10), plus or minus the number of items inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out). - will perform reloadData.

But it still throws a `NSInternalInconsistencyException` for section-level inconsistencies.

Reviewed By: patters

Differential Revision: D23386178

fbshipit-source-id: a9930b619701cffd37d0d6e2bcb1268ef7c9d0ce
2020-09-08 09:11:12 -07:00
Maxime Ollivier
ad5171978e create IGListUpdatingDelegateExperimental
Summary:
For diffing, `IGListAdapterUpdater` uses the full `fromObjects` instead of `validObjects`, which can be different if we're missing `IGListSectionController`. The diffing results won't match what the `IGListAdapter` tells the `UICollectionView`, so we can crash.

To fix this, lets try to generate the `IGListSectionController` before performing the diffing, and keep them in a container object (`IGListTransitionData`) alonside the `fromObjects` and `toObjects`. This might also unblock other cool features in the future, like giving `IGListSectionControllers` time for background work, but that's for another day.

Since this change is relatively large, lets create a temporary protocol `IGListUpdatingDelegateExperimental` which will have a slightly different API from `IGListUpdatingDelegate`. When/if the new implementation ships, we can merge both protocols.

Why not edit `IGListAdapterUpdater` directly?
* I don't want to mess up exiting updaters just yet.

Reviewed By: patters

Differential Revision: D23145776

fbshipit-source-id: 21642cafa64e2a26a173e2ba683ef5c6cede17d7
2020-09-08 09:11:11 -07:00
Maxime Ollivier
aca18c7470 ship IGListExperimentSkipLayoutBeforeUpdate
Summary: Experiment looks good, so lets ship.

Reviewed By: patters

Differential Revision: D23145775

fbshipit-source-id: 16da69f220a2247490bb99b4965bcba33f498ced
2020-09-08 09:11:11 -07:00
Maxime Ollivier
254c04196a remove unused experiment param
Summary: We pass `experiments` to places that don't need it, so lets clean that up.

Reviewed By: patters

Differential Revision: D23145782

fbshipit-source-id: affcfe0f38d1b8e544940af89e5692dbdc36dd76
2020-09-08 09:11:11 -07:00
Maxime Ollivier
0769da43df NSSet and NSArray optimization
Summary:
On `IGListAdapater` data update:
1) Pass the capacity count, so that arrays don't have to re-size.
2) Avoid using a set, so that we don't need to deal with hashes and equality. The updater should have dealt with duplicates already.

Reviewed By: patters

Differential Revision: D23145771

fbshipit-source-id: 2ed93231e15ddcd66cfe4d1f7384c563c77caa8e
2020-09-08 09:11:11 -07:00
Maxime Ollivier
e3e26c4b4b test skipping layout before performing updates
Summary: We call `[collectionView layoutIfNeeded]` before performing updates, but it's not clear why. It leads to some strange animation issues when performing updates while scrolling. So lets try to skip it?

Reviewed By: Haud

Differential Revision: D22244053

fbshipit-source-id: 0c01a73860ebc16f430fed04d5c29a5bde038286
2020-06-26 10:07:14 -07:00
Maxime Ollivier
86ecc60085 clean up IGListExperimentReloadDataFallback
Summary: This experiment shipped so we can remove it. We still need a way to disable it with `allowsReloadingOnTooManyUpdates` in case we don't want to resign the first responder on large updates.

Reviewed By: Haud

Differential Revision: D22219238

fbshipit-source-id: 98e78f3ed040809db6c4b4c8da8fd0e976aca0a2
2020-06-26 10:07:13 -07:00
Maxime Ollivier
7fc4384a78 clean up IGListExperimentDeferredToObjectCreation
Summary: Experiment shipped.

Reviewed By: Haud, lorixx

Differential Revision: D22219240

fbshipit-source-id: 9299d1371b87593fcbece4557cf760cb9c42e1fe
2020-06-26 10:07:13 -07:00
Maxime Ollivier
34c935c1a5 clean up IGListExperimentGetCollectionViewAtUpdate
Summary: Experiment shipped.

Reviewed By: Haud, lorixx

Differential Revision: D22219242

fbshipit-source-id: 60dbb5f008656ae67b02294ef16138703ebe392f
2020-06-26 10:07:13 -07:00
Maxime Ollivier
4cc65c6b7f remove IGListExperimentFixIndexPathImbalance
Summary: Actually this won't work and causes even more crashes. For example, if we reload cell 0 and insert at 0, we end up with just a single delete & insert at 0, which causes an inconsistency exception. `IGListApplyUpdatesToCollectionView` already takes care of avoiding multiple reloads of the same `NSIndexPath` by using a `NSMutableSet` when collecting the `reloadDeletePaths`.

Reviewed By: apadalko

Differential Revision: D21822502

fbshipit-source-id: c2382951ffe013f82c1de2492286d2911f40444d
2020-06-02 13:04:26 -07:00
Maxime Ollivier
ea03bc959d ship IGListExperimentAvoidLayoutOnScrollToObject
Summary: Remove `[collectionView layoutIfNeeded]` before scrolling in `[IGListAdapter scrollToObject...]` to avoid creating off-screen cells.

Reviewed By: apadalko

Differential Revision: D21822496

fbshipit-source-id: 3251beed489c1e3e8d7a872638e37a5580ec0f4f
2020-06-02 13:04:26 -07:00
Maxime Ollivier
677ce77eca ship IGListExperimentUseCollectionViewInsteadOfDataSourceInLayout
Summary: Ship this experiment. `IGListCollectionViewLayout` should get the section/index counts via `UICollectionView` to stay in sync, instead of the `dataSource`.

Reviewed By: apadalko

Differential Revision: D21789871

fbshipit-source-id: 9fe069bd793b36680cd8562e69c7367d69a11ec7
2020-05-29 16:19:37 -07:00