fix: guard accessibility updates behind window != nil#613
Draft
RoyalPineapple wants to merge 1 commit intomainfrom
Draft
fix: guard accessibility updates behind window != nil#613RoyalPineapple wants to merge 1 commit intomainfrom
RoyalPineapple wants to merge 1 commit intomainfrom
Conversation
d5c562b to
b191cde
Compare
2be57f7 to
80fc80a
Compare
ef494f7 to
3d5d788
Compare
…indow Prevents an AXRuntime crash (NSMapGet on a NULL element cache) when UIKit posts an internal accessibility notification in response to isAccessibilityElement = true on a view being added to the hierarchy. Under XCTest's test runner, the scene lifecycle is delayed and AXRuntime's element cache is still NULL when the notification fires. Move isAccessibilityElement = true from init to didMoveToWindow so the view only becomes an accessibility element after it has a window and AXRuntime is initialized. Guard CombinableView.isAccessibilityElement getter to return false when window is nil, ensuring UIKit never considers the view an accessibility element before the scene lifecycle is ready. Also guards CombinableView.updateAccessibility(), ReceiverContainerView.updateDeferredAccessibility(), and SourceContainerView.updateAccessibility() behind window != nil to prevent unnecessary accessibility work on views not in the hierarchy. Adds the missing accessibilityTraits lazy-update override on CombinableView for consistency with other property getters.
3d5d788 to
3aa5606
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
AXRuntime maintains an internal element cache (a map table) that is allocated during the scene lifecycle. Under XCTest's test runner, the scene lifecycle is delayed — the cache is still NULL when the first accessibility broadcast fires, and
NSMapGetcrashes on the NULL pointer.Root cause
ReceiverContainerView.initsetsisAccessibilityElement = trueduring init. When this view is added to the hierarchy viaaddSubview, UIKit internally posts an accessibility notification. Under XCTest's test runner, AXRuntime's element cache hasn't been allocated yet when that notification fires during a run-loop drain, crashing on the NULL map table.We can't guard UIKit's internal notification post — the fix is to not set
isAccessibilityElement = trueuntil the view is in a window, at which point the scene lifecycle has completed and AXRuntime is initialized.Evidence
xcodebuild testxcrun simctl launch(normal launch)NSMapGetwherex0 == 0hit the NULL map table.deferredAccessibilityReceiver()on views present during initial layoutFix
ReceiverContainerView: moveisAccessibilityElement = truefrominittodidMoveToWindow(). The view only becomes an accessibility element after it has a window. SetsisAccessibilityElement = falsewhen removed from a window. Also defersneedsAccessibilityUpdate = truetodidMoveToWindow()so the first accessibility update doesn't trigger before the scene is ready. Removed the redundantisAccessibilityElement = trueandneedsAccessibilityUpdate = truefrom thebackingViewDescriptionapply block sincedidMoveToWindowhandles both.CombinableView.updateAccessibility(),ReceiverContainerView.updateDeferredAccessibility(),SourceContainerView.updateAccessibility(): early-return whenwindow == nil. Defensive guards to prevent unnecessary accessibility work on views not in the hierarchy.Add missing
accessibilityTraitsoverride onCombinableView: the getter was missing the lazy-update pattern that all other accessibility property overrides use. Added for consistency.