не может удалить все изображения спрайт-контейнера - PullRequest
2 голосов
/ 20 мая 2011

У меня есть стопка изображений. Все эти изображения добавляются в контейнер спрайтов:

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 ]

5 голосов
/ 20 мая 2011

Попробуйте удалить их в обратном порядке.Возможно, вам не хватает удалений, потому что вы пытаетесь удалить их, находясь в прямом цикле.

for(var i:int=container.numChildren;i>=0;i--)
{
     var currImg:Sprite = container.getChildAt(i) as Sprite;
     container.removeChild(currImg);
}
3 голосов
/ 20 мая 2011

Я тоже столкнулся с этой проблемой.Что на самом деле не так, так это то, что вы шагаете по списку отображения И сокращаете его с каждой итерацией.В AVM2 глубина списка отображения автоматически управляется в этом контексте, и когда вы удаляете дочерний элемент, остальная часть глубины списка отображения настраивается.В любом случае, решение заключается в том, чтобы обернуть его в цикл while:

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

Обновление

Также одна заметка о вашем коде.Старайтесь не использовать новую ссылку на клип.Это вызовет проблемы в процессе сбора мусора во флэш-ВМ, который автоматизирован, и будут очищены только объекты, на которые есть ссылки или ссылки с использованием слабых ссылок.Таким образом, вы можете сделать одно из следующих действий:

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)));
}
1 голос
/ 20 мая 2011

Как и в ответе @ 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...
1 голос
/ 20 мая 2011

Этот код будет работать:

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

Теперь, когда вы в первый раз проходите цикл, вы удаляете cat, поскольку его местоположение равно 0 в списке отображения. Вот как выглядит список отображения:

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

Обратите внимание, что индексы списка отображения сместились в зависимости от удаленного дочернего элемента. Не может быть пробелов в списке отображения по дизайну.

Итак, в следующий раз в цикле значение i будет 1 - верно? Это означает, что «птица» будет удалена из списка отображения, в отличие от собаки, что вы могли ожидать.

так вот список отображения после этого в следующий раз в цикле:

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

Так что да. Многие из этих решений будут работать. В этом случае я бы рекомендовал цикл while. Но я думаю, что реальным знанием, которое можно получить из этого вопроса, является понимание проблемы.

...