2

Inside my Document Class I have assign to an array some objects that are placed on stage so I can call them later.

When I declare the array outside the constructor the objects haven't been created and the assign values are null unlike when I declare them inside constructor. Why is this happening?

How can I avoid this?Can I use a listener to track when objects are loaded?

First Case

package { 
   public class Document extends MovieClip {
       var obj:Array = [object1,object2];
       public function Document() {
          trace(obj[0]); // <-- null
       }
   }
}

Second Case

package { 
   public class Document extends MovieClip {
       public function Document() {
          var obj:Array = [object1,object2];
          trace(obj[0]); // <-- reference value
       }
   }
}

enter image description here enter image description here enter image description here

giannis christofakis
  • 8,201
  • 4
  • 54
  • 65

3 Answers3

3

Global variables (i.e. the ones outside any method) are loaded prior to anything, after the constructor is called and before it is executed.

Use this code instead:

package { 
   public class Document extends MovieClip {
       var obj:Array;
       public function Document() {
          obj = [object1,object2];
          trace(obj[0]);
       }
   }
}

ADDENDUM:

Stage objects are initialized at the top of constructor code, like designer objects are in .net for example.

So, since global variables are initialized prior to the execution of constructor code, object1 and object2 are still null.

ADDENDUM 2:

You have the following sequence:

  1. Constructor of class is called
  2. Global variables are initialized (your obj array, and also object1/object2 variables, but not their value)
  3. Designer (your graphics on the stage) objects are initialized (that is object1 = new Object1() is called)
  4. Constructor code is executed

Stage objects are always automatically declared and initialized, unless you de-check Automatically declare stage instances in Advanced AS settings.

Teejay
  • 7,210
  • 10
  • 45
  • 76
  • Can you explain me why the Document constructor is called before the stage objects are placed? – giannis christofakis Dec 07 '12 at 12:08
  • 2
    The objects are children of the Document, hence the Document has to be created before them. – Dave Hart Dec 07 '12 at 12:14
  • I find it easiest to think of this as the stage (as in where objects are placed in the IDE document) is _inheriting_ from the Document Class. This means the document class have no concept about the declared objects on the stage until the child class (IDE stage) have been instantiated. – david.emilsson Dec 07 '12 at 12:30
  • @DaveHart Very nice explanation,is there a way to certify that objects are created on stage or it is implied when we call the constructor? – giannis christofakis Dec 07 '12 at 12:32
1

Declare the array outside, and stuff values inside the constructor.

public class Document extends MovieClip {
   var obj:Array;
    public function Document() {
      obj = [object1,object2];
      trace(obj[0]); // <-- reference value
   }
}

Whatever you write as initialized value is processed first, anything embedded in editor is second, the constructor code is third. So, when you refer assets by name in initialization code, they are yet uninitialized, so you receive nulls.

Whatever listeners you use will only get applied after the object will be available. init() and ADDED_TO_STAGE listeners are useful if you need stage reference to align your code-controlled asset to given stage dimensions. Before that happens, the stage reference is null.

Vesper
  • 18,599
  • 6
  • 39
  • 61
  • I know the answer my question is why is this happening? – giannis christofakis Dec 07 '12 at 11:50
  • 1
    Because everything you initialize with code in declaration is processed first, stage elements are processed second, constructor code is processed third. So, when an out-of-constructor initialization code is processed, `object1` and `object2` are yet uninitialized, so you get nulls. – Vesper Dec 07 '12 at 12:33
  • @Vesper You can change your current answer with your comment if you want and the correct answer is yours. Another thing, can I use `Event Listener onLoad`,some `init()` function,`ADDED_ON_STAGE` or it's unnecessary? – giannis christofakis Dec 07 '12 at 12:48
  • No need to use those listeners in this context – Teejay Dec 07 '12 at 16:13
-2

Well this is kind of vague. Where are those objects instantiated? I would suggest making sure they are instantiated in you class:

package
{
    public class Document extends Sprite //I don't think you really need MovieClip
    {
        //alternatively to the method bellow you could use something like:
        //
        // private var object1 : Object = new Object();
        // private var object2 : Object = new Object();
        // public var obj : Array = [object1, object2];
        //
        // just make sure they are instantiated before they are used in the obj contructor

        public var obj : Array = [new Object(),new Object()]; //again here I would suggest using a vector if they are the same type

        public function Document()
        {
            trace(obj[0]);
        }
    }
}

If those objects are external to the class I would suggest passing them to the contructor like this:

package
{
    public class Document extends Sprite //I don't think you really need MovieClip
    {
        public var obj : Array = [null,null]; //again here I would suggest using a vector if they are the same type

        public function Document(o1:Object=null,o2:Object=null)
        {
            if (o1 != null)
                obj[0] = o1;
            if (o2 != null)
                obj[1] = o2;
            // 
            if (obj[0] != null)
                trace(obj[0]);
            else
                trace("Obj[0] is null");
        }
    }
}

[LATER EDIT] As to the reason this is happening is because at the time of the array initialization those 2 are null (they haven't been initialized yet)

[LATER EDIT2] OK - Document is the root class of the flash - good to know Like I said in my comments, even though on stage those 2 objects aren't instantiated until they are added to stage. for that I would suggest listening to the ADDED_TO_STAGE event. if you pass them outside constructor they will be null when the array is created since they haven't yet been added to stage/created(contrary to popular belief, even in Flash, objects don't simply exist)

Urash
  • 13
  • 6
  • 1
    No, they're on the stage. PLEASE READ THE QUESTION! – Teejay Dec 07 '12 at 11:52
  • before casting a -1 vote please do ACTUALLY READ the answer. That being said, please do explain how do you expect your class to actually know who those objects are ? Where do you pass the reference to those objects? Like I said be more specific before in your question and you'll get more exact answer. Casting -1 votes to discredit people will only get you banned as long as you don't have a valid reason to do so. – Urash Dec 07 '12 at 11:58
  • Don't want to discredit you, but your answer that do not add something useful to the post. You wrote "Well this is kind of vague. Where are those objects instantiated?", so it means you actually didn't read the question, because @yannis hristofakis specified that objects are on the stage. In Flash, objects on the stage are automatically declared and initialized (unless you mark a specific option). – Teejay Dec 07 '12 at 12:05
  • I don't know wher you learned flash but clearly you had a bad teacher. In flash objects declared on stage aren't available in all classes in that swf. In order for an object to be available in a class they have to be specifically instantiated// passed on to the class. Even on stage they aren't instantiated until the stage is actually displayed - for that there is Event.INITIALIZE and Event.ADDED_TO_STAGE - I know you believe those are useless events but they really aren't. Oh, and @teejay please don't show off how low your flash knowledge is. – Urash Dec 07 '12 at 12:07
  • I never said that they are "available in all classes in that swf". He declared it on the stage and he use them in the Document class (that is class of the main stage) so, yes, the're available! Moreover, objects are available when they are created (that is, in this case, when the class in initialized), NOT when added on stage. The ADDED_TO_STAGE event is not important in this topic. – Teejay Dec 07 '12 at 12:17
  • I well know my knowledge level of flash, so please don't bother me more only because I marked down your answer. – Teejay Dec 07 '12 at 12:18
  • Yes ..he told that in his 3rd edit not when I initially answered - and I can clearly see your Flash level since you don't know that objects aren't on stage until the ADDED_TO_STAGE event was fired. – Urash Dec 07 '12 at 12:19
  • Actually, he wrote it in the first line and when initially posted. Check that here: http://stackoverflow.com/posts/13762206/revisions – Teejay Dec 07 '12 at 12:23
  • I never said that objects are on the stage before ADDED_ON_STAGE. I said that they are available, i.e. you can access them programatically. – Teejay Dec 07 '12 at 12:25
  • Where does it say that the Document class is the root class of the swf? I can see that just after he posted the screens (not available in his first post) - so again am I supposed to guess that is the root class of the swf? - they aren't available until they are initialized since the array is constructed before they are added to stage they won't be available - hence the issue, because you are trying to build an array with objects that aren't yet available. – Urash Dec 07 '12 at 12:27
  • 2
    Document class is the generic name of the main stage class, since Flash CS3, so no need to suppose. http://active.tutsplus.com/tutorials/actionscript/quick-tip-how-to-use-a-document-class-in-flash/ – Teejay Dec 07 '12 at 12:39
  • too bad I develop in Flash Builder – Urash Dec 07 '12 at 12:40