[ALOY-897] Adding a Widget that uses arguments to a controller's XML causes a Proxy leak
GitHub Issue | n/a |
Type | Bug |
Priority | High |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2014-01-06T17:39:18.000+0000 |
Affected Version/s | Alloy 1.2.2 |
Fix Version/s | Alloy 1.4.0 |
Components | Widgets |
Labels | qe-closed-3.3.0, qe-testadded |
Reporter | Alan Leard |
Assignee | Tony Lukasavage |
Created | 2013-12-06T01:09:05.000+0000 |
Updated | 2014-05-14T09:52:13.000+0000 |
Description
Description
Proxies do not get released from a window that has a widget added to in in the XML (widget has to be using arguments).
Repro Steps
-Build attached app.
-Open Xcode Instruments.
-Open the new window, then close it.
-Repeat several times and you will find that Proxies are retained while UIViews are released.
-Comment out line 4 of LandingPage.xml to remove the widget, then repeat steps. The leak goes away.
Attachments
Found the root of the issue, and Alan's hint that it required arguments being passed to the widget is what helped me find it. At the beginning of the loading widget's controller, all arguments are attached to the loading UI proxy, like this:
This is meant to attach any arguments passed through
__parentSymbol
property, which holds a reference to the parent of this widget, is being attached to the loading UI proxy. When the widget is removed, it retains this__parentSymbol
reference unbeknownst to the developer, and in turn stays in memory since this reference is never nulled out, and hence the seemingly unavoidable memory leak. So technically this memory leak is not inherent in Alloy, but is a result of the widget attempting to iterate through all given arguments and attach them to the proxy without validation. It is actually really easy for the widget to be updated to avoid this. That said, the hidden properties Alloy attaches should not be enumerable, and this type of problem should not even be possible. Here's what will be done:Make a small modification to the loading widget to more deliberately handle the incoming arguments, which would prevent the memory leak in this widget and address the immediate problem.
Use the
Object.defineProperty()
function to make Alloy's hidden variables non-enumerable, which would prevent any other widgets from falling victim to this trap.The loading widget, the only builtin Alloy widget affected by this, has been fixed in ALOY-898. The underlying issue yet to be addressed here can be worked around on of 2 ways in the meantime:
Don't blindly iterate over the properties in the "args" object as they will contain Alloy hidden properties
Use the following code snippet to safely ignore Alloy hidden properties when iterating over "args":
PR: https://github.com/appcelerator/alloy/pull/294 Functional test can be run against the app given in the description to ensure that no memory leaks occur.
Verified the FIXED with: Appc-Studio:3.3.0.201405121247 sdk:3.3.0.v20140513191712 acs:1.0.14 alloy:1.4.0-dev npm:1.3.2 titanium:3.3.0-dev titanium-code-processor:1.1.1 xcode:5.1.1 Device:Iphone Simulator(v7.1) Ran the app found no memory leaks. Working as expected. Hence closing the issue.