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);
}

3 Responses to “Forcing class import with dynamic classes in AS3”

  1. Chris says:

    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?

  2. paul says:

    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.

  3. David Peers says:

    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.

Leave a Reply