Forcing class import with dynamic classes in AS3
Recently I came upon a situation where I’m trying to dynamically instance classes based off meta data loaded externally. Flex compiles ok, but running fails… Futher investigation while debugging during runtime shows the following error:
ReferenceError: Error #1065: Variable MyClass is not defined.
It turns out, that because I have no reference to using the class statically, the compiler is optimizing out the ‘MyClass’ class.
Since there appears to be no compiler directive to force a class to include (the import statement doesn’t force it) by using it once.
The easiest thing to do is just create an array of all my dynamic classes, as so:
var forceIncludeClasses:Array = [
MyClass,
MyClass2,
MyClass3
];
Since I’m calling this from an init function, there should only be a microsecond of slowdown during startup and the array’s scope isn’t global so the garbage collector should clean it up.
Here is a more complete snippet of using dynamic classes.
/* import my classes */
import com.noinc.MyClass;
import com.noinc.MyClass2;
import com.noinc.MyClass3;
/* the utility import that allows us to get a class reference to my dynamic classes */
import flash.utils.getDefinitionByName;
/* init function, called at creationComplete */
function init():void
{
var forceIncludeClasses:Array = [
MyClass,
MyClass2,
MyClass3
];
createInstance("com.noinc.MyClass");
}
/* called to create instances of my classes */
function createInstance(className:String):void
{
/* className is a string reference to my class, using the full package name, coming from XML in my code */
/* Even though statically I could just do var x:MyClass = new MyClass(), getDefinitionByName */
/* Appears to not be happy with just MyClass... */
/* A handle to the class is returned */
var tmpClass:Class = getDefinitionByName(className) as Class;
/* We are using * for our variable type because we don't know ahead of time what class this function will use */
var tmpOb:* = new tmpClass();
/* set whatever additional properties you want */
tmpOb.property = "whatever";
/* Add the instance to the stage */
addChild(tmpOb);
}

Nice article, Paul!
It’s a shame we need to include the package name when using “getDefinitionByName”, though – it forces us into a certain package structure, or to use additional conditions..
Has anyone found a way around this?
Well even in adobe’s examples they use the full package name, e.g. [http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/utils/package.html#getDefinitionByName%28%29]
You could make a lookup table. So you can pass in ’sprite’ and it knows to use flash.display.Sprite, then ‘box’ and it uses com.custom.Box.
Thanks, this blog helped me somewhat in solving some problems with the latest release, Why do they always leave out vital information when they release a new version? It may be minor to them but not for us! I’m sure we’re not alone either.