mirror of
https://github.com/Instagram/IGListKit
synced 2026-04-21 13:37:19 +00:00
Summary: https://github.com/Instagram/IGListKit/issues/1658 This fix addresses a crash that occurs when VoiceOver is enabled and `scrollViewDelegate` or `collectionViewDelegate` is set to the adapter's own `UICollectionView`. ## The Problem When VoiceOver is enabled, accessibility queries trigger delegate method calls on the collection view. If the collection view is also set as its own scroll view delegate (via `IGListAdapter`'s proxy), these delegate calls get forwarded back to the collection view, creating infinite recursion: 1. VoiceOver queries accessibility on collectionView 2. `collectionView.delegate` (the proxy) forwards to `scrollViewTarget` 3. `scrollViewTarget` IS the collectionView → back to step 1 4. Stack overflow crash Example crash-triggering code: ``` adapter.collectionView = collectionView adapter.scrollViewDelegate = collectionView // Crash with VoiceOver! ``` ## The Fix Here I've added validation in three places to prevent this configuration: 1. `setScrollViewDelegate:` - Rejects if `delegate == collectionView` 2. `setCollectionViewDelegate:` - Rejects if `delegate == collectionView` 3. `setCollectionView:` - Clears delegates if they equal the new collectionView ## Why This Is Safe (No Negative Side Effects) **Setting UICollectionView as its own delegate provides no useful functionality:** - `UICollectionView` already handles scroll events internally (it's a `UIScrollView` subclass) - The `collectionView` doesn't implement custom `UIScrollViewDelegate` methods - This configuration ONLY results in crashes when VoiceOver is enabled **Behavior change is strictly beneficial:** - Before: Works without VoiceOver, crashes WITH VoiceOver - After: Silently rejects invalid config, works with VoiceOver **Developer feedback is preserved:** - `IGFailAssert` fires in `DEBUG` builds to alert developers to fix their code - Production gracefully handles the situation instead of crashing **No breaking changes for valid usage:** - Normal delegate patterns (separate delegate objects) are unaffected - Only the invalid self-referential pattern is blocked See: https://github.com/Instagram/IGListKit/issues/1658 Reviewed By: dinhvh Differential Revision: D100641752 fbshipit-source-id: a1885c4ede6ca0555f3f94dd0c72b328a5af62bc |
||
|---|---|---|
| .. | ||
| Assets | ||
| Objects | ||
| IGListAdapterDelegateAnnouncerTests.m | ||
| IGListAdapterE2ETests.m | ||
| IGListAdapterProxyTests.m | ||
| IGListAdapterStoryboardTests.m | ||
| IGListAdapterTests.m | ||
| IGListAdapterUpdaterTests.m | ||
| IGListBatchUpdateDataTests.m | ||
| IGListBindingSectionControllerTests.m | ||
| IGListBindingSingleSectionControllerTests.m | ||
| IGListCollectionScrollingTraitsTests.m | ||
| IGListCollectionViewLayoutTests.m | ||
| IGListCollectionViewTests.m | ||
| IGListContentInsetTests.m | ||
| IGListDebugDescriptionTests.m | ||
| IGListDebuggerTests.m | ||
| IGListDiffDescriptionStringTests.m | ||
| IGListDiffResultTests.m | ||
| IGListDiffSwiftTests.swift | ||
| IGListDiffTests.h | ||
| IGListDiffTests.m | ||
| IGListDisplayHandlerTests.m | ||
| IGListGenericSectionControllerTests.m | ||
| IGListInteractiveMovingTests.m | ||
| IGListItemUpdatesCollectorTests.m | ||
| IGListKitTests-Bridging-Header.h | ||
| IGListPerformDiffTests.m | ||
| IGListReloadDataUpdaterTests.m | ||
| IGListSectionControllerTests.m | ||
| IGListSectionMapTests.m | ||
| IGListSingleNibItemControllerTests.m | ||
| IGListSingleSectionControllerTests.m | ||
| IGListSingleStoryboardItemControllerTests.m | ||
| IGListTestCase.h | ||
| IGListTestCase.m | ||
| IGListTestHelpers.h | ||
| IGListTransactionTests.m | ||
| IGListUpdateCoalescerTests.m | ||
| IGListViewVisibilityTrackerTests.m | ||
| IGListWorkingRangeHandlerTests.m | ||
| Info.plist | ||
| UIViewControllerIGListAdapterTests.m | ||