Repository navigation
fix(iOS): Make components measuring safer for the Main Thread - #852
Merged
Merged
Conversation
Closed
3 tasks done
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
A timed-out initial measurement can leave nonempty EnrichedText collapsed because snapshot updates do not invalidate Yoga’s cached zero height, requiring measurement invalidation when the snapshot changes.
1 open issue
What changed in this PR
This PR addresses the iOS measurement deadlock reported in #848 by replacing live component references with attributed-string snapshots, allowing mounted components to be measured without waiting on the main thread.
Changes:
- Publish measurement snapshots through Fabric state for text and input components.
- Measure snapshots independently of their UIKit views.
- Limit main-thread waits for initial mock measurements to 100 ms, falling back to zero height.
| File | Description |
|---|---|
ios/internals/EnrichedTextViewState.h |
Stores the snapshot and text layout settings. |
ios/internals/EnrichedTextViewState.cpp |
Exposes snapshot and layout-setting getters. |
ios/internals/EnrichedTextViewShadowNode.mm |
Measures snapshots with a bounded mock fallback. |
ios/internals/EnrichedTextViewShadowNode.h |
Makes mock creation independent of node lifetime. |
ios/internals/EnrichedTextInputViewState.h |
Replaces the component reference with a snapshot. |
ios/internals/EnrichedTextInputViewState.cpp |
Exposes the input snapshot getter. |
ios/internals/EnrichedTextInputViewShadowNode.mm |
Measures input snapshots with a bounded mock fallback. |
ios/internals/EnrichedTextInputViewShadowNode.h |
Makes input mock creation independent of node lifetime. |
ios/internals/EnrichedMainThreadMeasure.h |
Adds the shared timeout-based measurement helper. |
ios/EnrichedTextView.mm |
Creates, publishes, and measures text snapshots. |
ios/EnrichedTextView.h |
Declares snapshot-based text measurement. |
ios/EnrichedTextInputView.mm |
Creates, publishes, and measures input snapshots. |
ios/EnrichedTextInputView.h |
Declares snapshot-based input measurement. |
Review effort: Balanced
exploIF
approved these changes
Nov 4, 2026
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.

Summary
This PR aims to fix issue: #848
Basically, there was a possibility to have a native main thread deadlock because we were force-running some operations on it.
What the fix does:
snapshotwhich is the attributed string currently sitting in the component (and alsomaximumNumberOfLines+lineBreakModefor the text component, because measuring depends on them except the attributed string snapshot).These let us free the main thread - there was a possible scenario that some layout operation locks the main thread and calls our component's measure on a non-main one. In the previous iteration we would endlessly wait for the main thread dispatch to go through. Now the regular measures don't need to be run on main thread and the special "mock" ones (which still require the main thread) have a safeguard to not wait endlessly for it.
Other fix
The second commit also fixes related dirty-layouting issues I found when fixing this one:
React Native anyway always marks freshly cloned nodes dirty (up for a layout) but I made these changes to not blindly rely on this behavior.
Test Plan
As I could not reproduce the issue, it's all up to the issue author to test out the patch from this PR.
Screenshots / Videos
Compatibility
Checklist