[UPDATE: It looks like Colin Moock‘s excellent book Essential ActionScript 2.0 talks about this very situation, on page 328. His workaround is to use setInterval
to poll the object to see if the custom methods/properties have been set up yet.]
This kind of stuff is always a bit difficult to describe clearly, so I might not even try :P So here are some scratched-in notes for myself:
- Imagine a MovieClip (mc1) which contains another MovieClip inside it (mc2). This nested instance is created in the authoring tool. It would look like this in the Movie Explorer:
- Both MovieClips have (different) custom class: let’s call them
MovieClass1
and MovieClass2
.
The constructor for MovieClass1
looks like this:
class MovieClass1 extends MovieClip {
function MovieClass1()
{
trace("MovieClass1 ctor " + this);
}
} |
class MovieClass1 extends MovieClip {
function MovieClass1()
{
trace("MovieClass1 ctor " + this);
}
}
MovieClass2
‘s constructor looks shockingly similar:
class MovieClass2 extends MovieClip {
function MovieClass2()
{
trace("MovieClass2 ctor " + this);
}
} |
class MovieClass2 extends MovieClip {
function MovieClass2()
{
trace("MovieClass2 ctor " + this);
}
}
Ok. Now we place an instance of MovieClass1
on the stage, name it mc1
, and test the movie. Here is the traced output:
MovieClass1 ctor _level0.mc1
MovieClass2 ctor _level0.mc1.mc2 |
MovieClass1 ctor _level0.mc1
MovieClass2 ctor _level0.mc1.mc2
So we know that the constructor for the parent clip is called before the constructor of the child clip.
Note that this is quite unlike C++, for example, where member objects are created before the containing object’s constructor is called (see here for an example), and in fact can cause real issues. For example, suppose MovieClass1
‘s constructor wants to call custom methods of MovieClass2
. Those calls will fail because mc2 has not yet been initialized! Note that this only applies to methods and properties that exist in the custom class — the MovieClip exists, as a plain old MovieClip
, but the custom class hasn’t been associated with it yet.
Example:
MovieClass1.as:
class MovieClass1 extends MovieClip {
var mc2:MovieClip; /* placed in Flash authoring tool */
function MovieClass1()
{
trace("MovieClass1 ctor " + this);
mc2.customMethod();
}
} |
class MovieClass1 extends MovieClip {
var mc2:MovieClip; /* placed in Flash authoring tool */
function MovieClass1()
{
trace("MovieClass1 ctor " + this);
mc2.customMethod();
}
}
MovieClass2.as:
class MovieClass2 extends MovieClip {
function MovieClass2()
{
trace("MovieClass2 ctor " + this);
}
function customMethod()
{
trace("MovieClass2 customMethod()");
}
} |
class MovieClass2 extends MovieClip {
function MovieClass2()
{
trace("MovieClass2 ctor " + this);
}
function customMethod()
{
trace("MovieClass2 customMethod()");
}
}
The results of running this test:
MovieClass1 ctor _level0.mc1
MovieClass2 ctor _level0.mc1.mc2 |
MovieClass1 ctor _level0.mc1
MovieClass2 ctor _level0.mc1.mc2
Yep. customMethod()
is never called!
I hope to continue this in a later post… there are more details about the constructor-calling process that are weird and intriguing!