Skip to content

fix(ios): resolve pauseUnity, memory leaks, and Fabric issues#7

Draft
am-koan wants to merge 1 commit intomainfrom
koan/fix-ios-native-bugs
Draft

fix(ios): resolve pauseUnity, memory leaks, and Fabric issues#7
am-koan wants to merge 1 commit intomainfrom
koan/fix-ios-native-bugs

Conversation

@am-koan
Copy link
Copy Markdown

@am-koan am-koan commented Apr 20, 2026

What

Fix 8 iOS-side bugs in the Unity player lifecycle: broken pause/resume, memory leaks, crash-prone callbacks, and incomplete Fabric (New Architecture) support.

Why

Audit sessions identified these as HIGH and MEDIUM severity issues affecting all iOS users:

  • pauseUnity: never actually resumed — the BOOL * parameter type meant the pointer was always non-nil (truthy), so [[self ufw] pause:pause] always received true
  • initUnityModule leaked memory on every init (strdup'd argv strings + malloc'd array never freed)
  • onPlayerUnload/onPlayerQuit passed nil to RCTBubblingEventBlock, risking crashes
  • NativeCallProxy held a strong reference to the view forever, never cleared on unload
  • ViewManager methods operated on a file-global unity variable instead of the resolved view from viewRegistry
  • Fabric prepareForRecycle destroyed the singleton Unity runtime, breaking it for any future views
  • Fabric only wired onUnityMessage event emitter — onPlayerUnload and onPlayerQuit were silent
  • Fabric onUnityMessage lambda captured self as raw C++ pointer — dangling pointer risk

How

  • Change pauseUnity:(BOOL *) to pauseUnity:(BOOL) in header, implementation, and ViewManager
  • Free strdup'd strings and malloc'd array after runEmbeddedWithArgc: consumes them
  • Pass @{@"message": @"unloaded"} / @{@"message": @"quit"} instead of nil
  • Add unregisterAPIforNativeCalls method, call it in unloadUnity, guard sendMessageToMobileApp against nil api
  • Replace file-global unity with resolved view in all ViewManager methods
  • Remove unloadApplication from prepareForRecycle — only detach subviews
  • Wire onPlayerUnload and onPlayerQuit event emitters in Fabric initWithFrame
  • Use __weak/__strong self pattern in all Fabric event blocks
  • Respect androidKeepPlayerMounted prop in componentWillUnmount

Testing

No automated test runtime available for native code. Changes verified by code review against UnityFramework API and React Native bridging conventions. Each fix addresses a specific, documented failure mode.

Related


🤖 Generated with Claude Code

Fix pauseUnity parameter type from BOOL* (pointer) to BOOL — the pointer
was always non-nil, so Unity always paused and never resumed. Fix memory
leak in initUnityModule where strdup'd strings and malloc'd array were
never freed. Pass dictionary (not nil) to onPlayerUnload/onPlayerQuit
callbacks to prevent potential crashes. Add unregisterAPIforNativeCalls
to clear NativeCallProxy's strong reference on unload. Guard
sendMessageToMobileApp against nil api. Fix ViewManager using file-global
unity variable instead of the resolved view from viewRegistry. Fix Fabric
prepareForRecycle destroying the singleton Unity runtime. Wire up
onPlayerUnload and onPlayerQuit event emitters for Fabric (New Arch).
Fix Fabric onUnityMessage lambda to use weak self instead of capturing
raw C++ pointer. Respect androidKeepPlayerMounted in componentWillUnmount.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant