2

画像のスタックがあります。これらの画像はすべてスプライトコンテナに追加されます。

var container:Sprite = new Sprite();
container.addChild(img);//added in a loop
addChild(container);

後で、コンテナを繰り返し処理して画像を削除すると、次のようになります。

for(var i:int=0;i<container.numChildren;i++)
{
     var currImg:Sprite = container.getChildAt(i) as Sprite;
     container.removeChild(currImg);
}

画像の一部のみが削除されます。container.numChildrenをトレースすると、削除する画像の正しい数を取得します。誰かが同じ問題を抱えていましたか?

4

4 に答える 4

5

逆の順序で削除してみてください。フォワードバウンドループ中に削除しようとしているため、削除が欠落している可能性があります。

for(var i:int=container.numChildren;i>=0;i--)
{
     var currImg:Sprite = container.getChildAt(i) as Sprite;
     container.removeChild(currImg);
}
于 2011-05-20T17:06:15.133 に答える
3

私もこの問題に遭遇しました。ここで実際に間違っているのは、表示リストをステップアップし、反復ごとにそれを削減していることです。AVM2では、このコンテキストでディスプレイリストの深さが自動的に管理され、子を削除すると、残りのディスプレイリストの深さが調整されます。とにかく、解決策はそれをwhileループでラップすることです:

while(container.numChildren > 0){
    container.removeChildAt(0);
}

更新

また、コードに関する1つのメモ。クリップへの新しい参照をキャストしないようにしてください。これにより、フラッシュVMのガベージコレクションプロセスで問題が発生します。これは自動化されており、弱参照を使用して逆参照または参照されているオブジェクトのみがクリーンアップされます。したがって、次のいずれかを実行できます。

for(var i:int=0;i<container.numChildren;i++)
{
     var currImg:Sprite = container.getChildAt(i) as Sprite;
     container.removeChild(currImg);
     currImg = null;
}

また

for(var i:int=0;i<container.numChildren;i++)
{
     container.removeChild(Sprite(container.getChildAt(i)));
}
于 2011-05-20T17:09:45.190 に答える
1

このコードは機能します:

while(container.numChildren > 0)
{
    container.removeChildAt(0);
}

ただし、何が起こっているのかを理解できるように、そのループの何が問題になっているのかを指摘したいと思います。以下のコードに追加したトレースをコードに追加します。:

for(var i:int=0;i<container.numChildren;i++)
{
     trace (i + " : " + container.numChildren);
     var currImg:Sprite = container.getChildAt(i) as Sprite;
     container.removeChild(currImg);
}

ループを通過するたびに、子の数が予想どおりに減少することがわかります。

ただし、理解する必要があるのは、子が削除されると、コンテナの表示リストが非常に重要な方法で変化することです。

ループを実行する前のディスプレイリストの外観の例を次に示します。これらの前にある数字は、コンテナのディスプレイリストでの位置です。

0-cat
1-dog
2-bird
3-cow
4-elephant
5-clown

これで、ループを初めて通過するときに、猫を削除します。これは、猫の位置がディスプレイリストで0であるためです。表示リストは次のようになります。

0-dog
1-bird
2-cow
3-elephant
4-clown

削除された子に基づいて、ディスプレイリストのインデックスがシフトしていることに注意してください。設計上、ディスプレイリストにギャップを設けることはできません。

したがって、次にループを通過するとき、iの値は1-ですよね?つまり、犬とは対照的に、「鳥」が表示リストから削除されます。これは、予想していたことです。

次回ループを通過した後の表示リストは次のとおりです。

0-dog
1-cow
2-elephant
3-clown

あ、はい。これらのソリューションの多くは機能します。この場合、whileループをお勧めします。しかし、この質問から得られる本当の知識は、問題を理解することだと思います。

于 2011-05-20T17:44:10.587 に答える
1

@Michaelの回答と同様に、「numChildren」サイズが減少し、ループごとにイテレータが増加しているため、元のコードには削除がありません。

@Ascension Systemsが指摘したように、これが最良のアプローチです。

while(container.numChildren > 0){
  container.removeChildAt(0);
}

ただし、ループで実行する場合は、逆に実行する必要があります。

for(var i:int=container.numChildren;i>=0;i--){
  container.removeChild(container.getChildAt(i));
}

元のコードで何が起こるかを説明するために、25人の子を持つ次の例に注意してください。

フォワードループで削除すると、これが(各反復で)発生します。

i:0 Array length:24
i:1 Array length:23
i:2 Array length:22
i:3 Array length:21
i:4 Array length:20
i:5 Array length:19
i:6 Array length:18
i:7 Array length:17
i:8 Array length:16
i:9 Array length:15
i:10 Array length:14
i:11 Array length:13
//the remaining 12 items never get looped over...
于 2011-05-20T18:05:45.430 に答える