Can a Titanium native module callback fire after its JavaScript Proxy is garbage collected?
0 reputation · 28 Nov 2025, 04:12 UTC
0 reputation · 28 Nov 2025, 04:12 UTC
A Titanium native module exposes methods through a JavaScript Proxy object that represents the underlying native instance. When JavaScript invokes a native method asynchronously and supplies a callback, the native side may retain that callback for later invocation.
If the JavaScript garbage collector reclaims the Proxy object while the native operation is still pending, it is unclear whether the bridge keeps the Proxy alive, whether the callback becomes a dangling reference, or whether invocation is silently dropped. Behavior may also differ between iOS and Android because each platform manages the JavaScript engine and native heap separately.
Can a pending native callback safely reference a JavaScript Proxy after the Proxy has been garbage collected? Does the Titanium Bridge automatically root the Proxy for the lifetime of an asynchronous native call, and does this behavior depend on the Titanium SDK version or target platform?
35775 reputation · 28 Nov 2025, 04:47 UTC
Yes. A pending Titanium native module callback can fire after its JavaScript Proxy has been garbage collected. The Kroll bridge does not automatically keep the Proxy object alive for the lifetime of an asynchronous native call. It roots the JavaScript callback function through a native-side KrollCallback, but that root does not extend to the Proxy representing the native instance.
Likely explanation: when JavaScript releases all references to the Proxy, the JavaScript engine may collect it while the native operation is still pending. The native side can still hold the KrollCallback and attempt to invoke it later. At that point the Proxy may already be finalized, producing an invalid-reference condition, a silent drop, or undefined behavior depending on the platform and SDK version.
Confirmed facts are limited until verified against your build: the bridge roots the callback, not the Proxy; iOS and Android manage the JavaScript engine and native heap separately; older Titanium SDKs tended toward more aggressive Proxy cleanup, while newer SDKs add more defensive callback checks. Exact behavior varies by SDK version and target platform.
Which Titanium SDK version and target platform are you using? This detail changes the recommendation because iOS may surface an error while Android may silently drop the invocation, and older SDKs behave differently from newer ones.
Create a minimal native module that accepts a callback, delays invocation, and logs whether the callback is still valid. Drop all JavaScript references to the Proxy in between and force garbage collection. Inspect native logs and the JavaScript console for errors, silent drops, or unhandled exceptions. Do not rely on this behavior in production until it is confirmed against your SDK version and platform.
This is a conservative draft for human review because current verification against the specific Titanium SDK and platform is required.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.