-
Notifications
You must be signed in to change notification settings - Fork 116
Public Variables
It is pretty natural and common to just declare public variables on a class. As in:
public class MyClass
{
public var someVariable:Object;
}
However, public vars often do not survive minification and should be avoided for classes that will be used in MXML. Public methods and getters and setters will survive minification. Public "properties" for classes used in MXML should be defined via getters and setters.
If an application works in js-debug but not js-release, public variables are often at fault. The framework code has plenty of public vars because those classes were deemed to be not used from MXML. If a class with public vars does end up being used in MXML, that class should have its public vars rewritten as getter/setter.
We are still learning more about other scenarios that may fail in js-release due to renaming, so we may find that public variables always have to be rewritten as getter/setter.
The compiler has an option "-warn-public-vars" that is on by default. A warning message will be in the compiler output. The framework code should compile without these warnings. Either convert the var to getter/setter or suppress the warning via the @royalesuppresspublicvarwarning ASDoc directive. The directive can be used on each var or applied to an entire class. public vars with [Bindable] are exempt and should not cause the output of a warning because [Bindable] instructs the compiler to generate a getter/setter.
If a class is found to be at fault in js-release, check to see if @royalesuppresspublicvarwarning is used in the class and consider whether the renaming is at fault.
Currently, any public variable, getter/setter, or method is output with an @export directive. Such as:
MyClass = function();
/**
* @export
*/
MyClass.prototype.somePublicThing = function() {
}
The Google Closure Compiler renames somePublicThing to something short like "ah" and then generates an export reference like this:
MyClass.prototype.ah = function() {
}
MyClass.prototype.somePublicThing = MyClass.prototype.ah;
That way, all code that used to be "myClassInstance.somePublicThing()" can be shortened to "myClassInstance.ah" saving several bytes per use. But if someone were to write "myClass.somePublicThing()" or myClass["somePublicThing"]() in another module, it will find the renamed property. @export basically provides a reference with the original name to the shortened name, it does not actually prevent renaming.
For read-only class members like the methods and getter/setters, the export reference will reference the original function and all will be good.
But for public vars, the code is going to look like:
MyClass.prototype.ah = "foo";
MyClass.prototype.somePublicThing = MyClass.prototype.ah;
The problem is, if myClassInstance.ah is given a new value, myClassInstance.somePublicThing is still "foo". It was given a reference or value of ah at startup time.
MXML, DataBinding and States expect to be able to access the property by name and thus cannot work once ah is changed or ah is passed by value.
Apache®, Apache Royale, Royale™, and the Royale logo are either registered trademarks or trademarks of the Apache Software Foundation in the United States and/or other countries.