fix(ios): break retain cycle between renderers and RendererFactory#284
Merged
hryhoriiK97 merged 1 commit intosoftware-mansion-labs:mainfrom May 1, 2026
Merged
Conversation
Each renderer subclass held a strong reference to RendererFactory, which itself caches renderers in a strong-keyed dictionary. This created a retain cycle that ARC could not break, causing the factory and all renderers (plus their StyleConfig instances) to leak on every props update. The fix is to make the renderer's reference to the factory __weak, matching the pattern already used in ThematicBreakRenderer.m. AttributedRenderer.m remains strong since it is the actual owner of the factory. Verified via Instruments Leaks template before/after: previously the top of the leak list was dominated by RendererFactory, all renderer subclasses, and StyleConfig (~9 KiB each); after the fix, none of these classes appear in the leak list.
hryhoriiK97
approved these changes
May 1, 2026
Collaborator
hryhoriiK97
left a comment
There was a problem hiding this comment.
LGTM 🚀 @mgmx-io thank you for the fix! It will be available in tomorrow's nightly release.
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.
What/Why?
Closes #283
Each renderer subclass held a strong reference to
RendererFactory,which itself caches renderers in a strong-keyed dictionary. This
created a retain cycle that ARC could not break, causing the factory
and all renderers (plus their
StyleConfiginstances, ~9 KiB each)to leak on every props update — significant for
EnrichedMarkdownTextwith frequently changing
markdownprops (e.g. LLM streaming).Fix: change
_rendererFactoryfrom strong to__weakin all 15renderer subclasses.
AttributedRenderer.mremains strong since itis the actual owner of the factory. Matches the pattern already used
in
ThematicBreakRenderer.m.Testing
Profiled with Instruments → Leaks template, Release build on iPhone 15 Pro
(iOS 26), new architecture enabled. Same reproduction flow before and after.
Before: ~150 leaks per 30s scan, dominated by
RendererFactory,all renderer subclasses, and
StyleConfig.After: 0 library leaks. Only 1–2 unrelated
TextInputPropsleaks from React Native core remain.
Reproduced and verified via
patch-packageon a production appusing
EnrichedMarkdownTextfor LLM streaming.PR Checklist