Commit cc47ee4
Add IGListExperimentSkipNilIndexPathFiltering to opt into nil-index-path-aware visible cell filtering
Summary:
There's a subtle bug in `-[IGListAdapter visibleCellsForSectionController:]` and `-[IGListAdapter fullyVisibleCellsForSectionController:]`... both methods filter `[collectionView visibleCells]` by `[collectionView indexPathForCell:cell].section == section`, but `indexPathForCell:` is allowed to return `nil` for cells in transitional states — mid-`prepareForReuse`, mid-detach during a `performBatchUpdates`, or in flight between dequeue and final attachment. When that happens, sending `-section` to a `nil` `NSIndexPath` returns `0` in Objective-C, so any visible cell with a cleared index path is silently treated as belonging to **section 0**.
For most consumers this is harmless or invisible. But callers that walk these results and then read layout / window-relative geometry from each returned cell can end up touching cells whose model has been swapped out. We've seen this surface as crashes when a consumer triggers a layout pass on a cell whose backing data is mid-replacement (for example, text typesetting on an `NSAttributedString` that's being swapped out as the cell prepares for reuse). It's also a logical correctness issue: section 0 is the only section that can ever observe transitional cells from other sections leaking in.
The fix itself is essentially one line: skip cells where `indexPathForCell:` returned `nil` before doing the section comparison. The interesting question is how to roll it out.
Given how far-reaching this could be for code depending on IGListKit, I've introduced this as an opt-in experiment so we can effectively test this in Instagram and Threads before iterating or making an informed decision.
The fix is strictly subtractive — it can only narrow the result set, never expand it. Most consumers will just get more correct results. But these methods are called from a wide variety of places across multiple apps that depend on IGListKit, and we can't realistically audit every caller for code that may have implicitly leaned on the section-0 leak (for example, a state machine that flips the moment any cell becomes visible). Once it's been baked in across enough downstream consumers we can revisit and consider flipping the default or removing the flag entirely.
If you'd like to opt in yourself, you can set:
```objc
adapter.experiments |= IGListExperimentSkipNilIndexPathFiltering;
```
Differential Revision: D106699470
fbshipit-source-id: 966934aa7b1eefee3289d7d06c9a34e5a2ef0d351 parent ed04ffc commit cc47ee4
3 files changed
Lines changed: 84 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
31 | 37 | | |
32 | 38 | | |
33 | 39 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
37 | 42 | | |
38 | 43 | | |
39 | | - | |
| 44 | + | |
| 45 | + | |
40 | 46 | | |
41 | 47 | | |
42 | 48 | | |
43 | 49 | | |
44 | 50 | | |
45 | 51 | | |
46 | 52 | | |
47 | | - | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
48 | 58 | | |
49 | 59 | | |
50 | 60 | | |
| |||
1167 | 1177 | | |
1168 | 1178 | | |
1169 | 1179 | | |
1170 | | - | |
| 1180 | + | |
| 1181 | + | |
1171 | 1182 | | |
1172 | 1183 | | |
1173 | 1184 | | |
| |||
1176 | 1187 | | |
1177 | 1188 | | |
1178 | 1189 | | |
1179 | | - | |
| 1190 | + | |
| 1191 | + | |
1180 | 1192 | | |
1181 | 1193 | | |
1182 | 1194 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2345 | 2345 | | |
2346 | 2346 | | |
2347 | 2347 | | |
| 2348 | + | |
| 2349 | + | |
| 2350 | + | |
| 2351 | + | |
| 2352 | + | |
| 2353 | + | |
| 2354 | + | |
| 2355 | + | |
| 2356 | + | |
| 2357 | + | |
| 2358 | + | |
| 2359 | + | |
| 2360 | + | |
| 2361 | + | |
| 2362 | + | |
| 2363 | + | |
| 2364 | + | |
| 2365 | + | |
| 2366 | + | |
| 2367 | + | |
| 2368 | + | |
| 2369 | + | |
| 2370 | + | |
| 2371 | + | |
| 2372 | + | |
| 2373 | + | |
| 2374 | + | |
| 2375 | + | |
| 2376 | + | |
| 2377 | + | |
| 2378 | + | |
| 2379 | + | |
| 2380 | + | |
| 2381 | + | |
| 2382 | + | |
| 2383 | + | |
| 2384 | + | |
| 2385 | + | |
| 2386 | + | |
| 2387 | + | |
| 2388 | + | |
| 2389 | + | |
| 2390 | + | |
| 2391 | + | |
| 2392 | + | |
| 2393 | + | |
| 2394 | + | |
| 2395 | + | |
| 2396 | + | |
| 2397 | + | |
| 2398 | + | |
| 2399 | + | |
| 2400 | + | |
| 2401 | + | |
| 2402 | + | |
| 2403 | + | |
| 2404 | + | |
| 2405 | + | |
| 2406 | + | |
| 2407 | + | |
| 2408 | + | |
| 2409 | + | |
2348 | 2410 | | |
2349 | 2411 | | |
2350 | 2412 | | |
| |||
0 commit comments