2011-05-20 49 views
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,我會得到正確數量的要刪除的圖像。 有人有同樣的問題嗎?

回答

3

我也遇到過這個問題。這裏真正的錯誤在於,您正在逐步完成顯示列表,並在每次迭代時削減顯示列表。在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))); 
} 
+0

另一件事是關於人們發佈的代碼+你自己的代碼。在for循環中,您正在循環中投射變量「i」。儘量避免這種情況。在循環外部投射int,以便可以在for循環外部訪問範圍內的「i」,並在運行循環之後取消引用(即,在使用for循環的情況下)。循環不需要這個)。 – 2011-05-20 17:16:19

+0

「while」的方法完美工作,謝謝 – algro 2011-05-20 17:50:28

+0

for循環將工作,如果你改變getChildAt(i)getChildAt(0) – 2011-05-20 18:02:18

5

嘗試以相反的順序移除它們。可能是因爲你想在正向循環中刪除它們而丟失了刪除。

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

這正是他的問題,當他在索引0處移除孩子時,索引1處的孩子轉移到索引0,然後在循環的下一次迭代中,他將索引1處的孩子移除,使索引0處的孩子離開索引0 – 2011-05-20 17:46:58

+1

@The_asman是,但如果你從最高n開始刪除它們然後下降到0,所有這些都將被刪除(包括第0個位置)。嘗試一下。 – 2011-05-20 17:48:29

+0

是的,我同意你的說法,爲什麼我+1大聲笑只是指出爲什麼他的破產。 – 2011-05-20 18:04:47

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 

請注意,顯示列表索引已根據刪除的子級進行了移位。設計中不能在顯示列表上留下間隙。

所以,下一次通過循環,我的值是1 - 對嗎?這意味着「鳥」將從顯示列表中刪除,而不是狗,這是您可能預期的。

所以這裏通過循環下一次後顯示列表:

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

所以,是的。這些解決方案中的許多都可行。在這種情況下,我建議使用while循環。但我認爲從這個問題中獲得的真正知識是理解這個問題。

1

到@邁克爾的回答一樣,你原來的代碼失蹤清除,因爲你的「numChildren的」大小減少和你的迭代器的每一個迴路增加了對:

由於@Ascension系統指出,這是最好的辦法。

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...