2

ドキュメント クラス内で、ステージ上に配置されたいくつかのオブジェクトを配列に割り当てたので、後で呼び出すことができます。

コンストラクターの外側で配列を宣言すると、オブジェクトは作成されず、コンストラクター内で宣言する場合とは異なり、代入値は null になります。 なぜこれが起こっているのですか?

どうすればこれを回避できますか? リスナーを使用して、オブジェクトがいつロードされたかを追跡できますか?

最初のケース

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

2 番目のケース

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

ここに画像の説明を入力 ここに画像の説明を入力 ここに画像の説明を入力

4

3 に答える 3

3

グローバル変数 (つまり、メソッドの外側にある変数)は、コンストラクターが呼び出された後、実行されるに、何よりも先に読み込まれます。

代わりに次のコードを使用してください。

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

補遺:

ステージ オブジェクトは、たとえばデザイナー オブジェクトが.netにあるように、コンストラクター コードの先頭で初期化されます。

そのため、グローバル変数はコンストラクター コードの実行前に初期化されるため .object1object2null

補遺2:

次のシーケンスがあります。

  1. クラスのコンストラクターが呼び出されます
  2. グローバル変数が初期化されます(obj配列とobject1/object2変数ですが、その値ではありません)
  3. デザイナー (ステージ上のグラフィックス) オブジェクトが初期化されます (つまり、object1 = new Object1()呼び出されます) 。
  4. コンストラクターコードが実行される

Advanced AS 設定で[ステージ インスタンスを自動的に宣言する]のチェックを外さない限り、ステージ オブジェクトは常に自動的に宣言および初期化されます。

于 2012-12-07T11:44:47.883 に答える
1

外側で配列を宣言し、コンストラクターの内側に値を詰め込みます。

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

初期化された値として記述したものはすべて最初に処理され、エディタに埋め込まれたものはすべて 2 番目、コンストラクタ コードは 3 番目です。そのため、初期化コードでアセットを名前で参照すると、アセットはまだ初期化されていないため、null を受け取ります。

使用するリスナーは、オブジェクトが使用可能になった後にのみ適用されます。init()リスナーは、ADDED_TO_STAGEコード制御されたアセットを特定のステージ ディメンションに合わせるためにステージ参照が必要な場合に役立ちます。それが発生する前は、ステージ参照は null です。

于 2012-12-07T11:43:04.153 に答える
-2

うーん、これはちょっと曖昧です。これらのオブジェクトはどこでインスタンス化されますか? クラスでインスタンス化されていることを確認することをお勧めします。

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

これらのオブジェクトがクラスの外部にある場合は、次のようにコンストラクターに渡すことをお勧めします。

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

[後で編集]これが発生する理由は、配列の初期化時にこれら2つがnullであるためです(まだ初期化されていません)

[LATER EDIT2] OK - ドキュメントはフラッシュのルート クラスです - 知っておくとよい コメントで述べたように、ステージではこれら 2 つのオブジェクトはステージに追加されるまでインスタンス化されません。そのためには、ADDED_TO_STAGE イベントを聞くことをお勧めします。それらをコンストラクターの外に渡すと、それらはステージ/作成済みにまだ追加されていないため、配列が作成されるとnullになります(一般的な信念に反して、Flashでもオブジェクトは単に存在しません)

于 2012-12-07T11:51:21.967 に答える