티스토리 뷰

프로그래밍/잡탕

Removing Objects Properly

터프 프로그래머 2012. 1. 26. 05:20

http://developer.anscamobile.com/content/application-programming-guide-graphics-and-drawing#Removing_Objects_Properly
Corona SDK Docs >> Images, Shapes, and Text >> Working with Display Objects and the Stage 문서의
Removing Objects Properly ( 객체들을 적절히 지우기 ) 부분을 번역한 내용입니다.


기기의 자원은 한정되어 있기 때문에 display 객체들을 오래 사용하지 않을 때는 지워주는 것이 중요합니다. 메모리 소모(특히 이미지들)를 줄임으로써 전체 시스템의 성능향상과 불필요한 drawing을 없앨 수 있습니다.

당신이 display 객체를 만들 때, display 계층의 루트에 기본으로 추가됩니다. 이 객체는 특별한 그룹 객체인데 당신이 알고 있는 stage 객체 입니다.

화면에서 오래 render되지 않은 객체를 적절하게 삭제해주기 위해, 당신은  명시적으로 부모에게서 객체를 삭제해줄 필요가 있습니다. 이것은 display 계층에서 객체를 삭제합니다. 밑의 두 가지 방법으로 그것이 가능합니다.

image.parent:remove( image ) -- remove image from hierarchy
-- or --
image:removeSelf( ) -- same as above

그러나, 이것은 메모리를 점유한 이미지를 삭제하는 '항상' 바른 방법은 아닙니다. 이미지 객체가 가비지 콜렉트 목록에 바르게 추가되는 것이 보장되기 위해서는 다음 섹션에서 다룰 모든 참조를 없애 주는 것이 필요합니다.

Note : Starting with build 316, removing a group with object:removSelf will remove the group and all it's children. This will free up all object listeners and texture memory used by the Display Objects in the group and convert the Display Object variables into simple Lua tables. Lua will garbage collect the remaining Lua variables if there are no other references to the those variables. (See the next section on Varialbe References. )
Note : 빌드 316에서부터, object:removSelf로 삭제를 하면 그룹을 삭제하며 그 그룹의 자식들도 삭제합니다. 이것은 객체들의 리스너와 display 객체들의 텍스쳐 메모리 또한 삭제합니다.....



Variable References  변수 참조
display 객체가 계층에서 삭제되었더라도 객체가 계속 존재하는 경우가 있습니다. 위의 예제에서, 부모 그룹 solarSystem은 속성으로 행성의 이미지 객체를 저장합니다. 이미지를 display 계층에서 삭제한 뒤, 우리는 solarSystem이 더 이상 이미지를 참조하지 않도록 보장할 필요가 있습니다. 이렇게 하기 위해, 우리는 그 속성을 nil로 바꿔줍니다. ( 우리는 이것을 nil'ing하여 속성을 없앤다고 합니다. )
 

local
sun = solarSystem.sun sun.parent:remove( sun ) -- remove image from hierarchy solarSystem.sun = nil -- remove sun as a property of solarSystem

일반적으로, 여러분이 display 객체를 테이블 요소로 삽입할 때 그 display 객체가 화면에 표시되지 않더라도 그것의 존재를 유지합니다. 여러분은 위에서 한 것 처럼 속성을 nil로 처리해야 합니다.

비슷하게, display 객체를 가르키는 변수의 경우, display 객체는 그 객체가 존재하는 동안 메모리 해제될 수가 없습니다. 예를 들어, 글로벌 변수는 글로벌 변수가 display 객체를 가르키는 경우 절대 메모리 해제될 수 없고, 그것이 display 계층에 존재하지 않을 때 까지 계속됩니다. 이 때, 여러분은 글로벌 변수를 더 이상 사용하지 않을 때 nil로 수정해주는 것이 좋습니다.

또 다른 미묘한 부분은 함수가 지역 변수를 참조할 때 있습니다.

local sun = solarSystem.sun
 
function dimSun()
        sun.alpha = 0.5 -- sun was declared outside the function block
end

이 경우에, 특이하게 이미지 객체를 함수 내부에서 접근합니다. 이 함수는 글로벌 함수이기 때문에, 이미지 객체가 반드시 존재해야 합니다. 두 가지 해결방법이 있는데 : 함수를 글로벌 함수가 아니게 하는 것과 함수 블록 바깥의 변수가 참조되지 않도록 내용을 수정하는 것입니다. 후자가 더 바람직한 방법이며 모든 display 객체에 적용할 수 있는 일반적인 방법입니다.

local sun = solarSystem.sun
 
function dim( object )
        object.alpha = 0.5
end


Common Pitfalls  흔히 조심해야 할 점들 
흔히 하는 실수로 모든 객체들을 그룹에서 삭제하는 것이 있습니다. 이것은 일반적으로 순환자로 그룹의 자식들을 display 계층으로부터 삭제를 시도할 때 발생합니다.  이것은 정방향으로 순환자를 돌릴 때는 자연스러우나, 이것은 끝 없는 혼란을 일으킬 수 있습니다.

우리의 태양계 예제를 계속 이어가자면 밑에서 우리는 태양계의 모든 객체를 지우려고 합니다.

for i=1,solarSystem.numChildren do
        local child = solarSystem[i]
        child.parent:remove( child )
end

여기서 문제는 우리가 수정된 콜렉션을 계속해서 반복한다는 것에 있습니다. 결과는 모든 다른 자녀들을 지웁니다. 이것을 설명하는 가장 쉬운 방법은 아래와 같은 정수들로 이루어진 배열을 예로 드는 것입니다.

local array = {1,2,3,4,5,6,7,8,9,10}
print( table.concat( array, " " ) ) --> 1 2 3 4 5 6 7 8 9 10
 
for i=1,#array do
        table.remove( array, i )
end
 
print( table.concat( array, " " ) ) --> 2 4 6 8 10

이것을 고치려면 뒤에서부터 순환하면 됩니다.

for i=solarSystem.numChildren,1,-1 do
        local child = solarSystem[i]
        child.parent:remove( child )
end

당연히 이것은 display 계층으로부터 모든 자녀 객체들이 지워졌음을 보장합니다; 여러분은 여기서도 참조하는 모든 display 객체를 nil로 수정해주어야 합니다. 이 예제에서, 우리는 흔히 발생하는 문제들 중에서 단지 정방향 순환자에 대해서만 보았습니다.  여기서 중요한 것은 적절히 메모리를 비워주기 위해서는 해당 속성들을 지워줄 때 nil로 수정을 해주는 것이 필요하다는 것입니다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday