순환문과 인스턴스네임 다시 생각해보기
by 세계의끝 on 8.27, 2010, under 고수들은 가르쳐주지 않는 AS3.0 입문

순환문만 있다면 수백만번의 반복 노가다도 문제 없다.
부제: AS2.0의 인스턴스 네이밍 습관을 AS3.0에서 바꿔보자.
액션스크립트로 처음 개발언어에 입문한 사람들에게 순환문은 마법과도 같은 생산성을 의미합니다. 스테이지와 타임라인에 드로잉 툴로 이것저것 그려내고 모션 트윈이나 쉐이프 트윈 노가다를 하던때가 매우 미개하게 느껴질 만큼 그 위력은 대단하게 느껴지죠.
액션스크립트에서 사용할 수 있는 순환문에는 while, do .. while, for, for .. in, for each .. in 의 다섯가지 입니다.[01] 앞의 세 가지 순환문은 각기 형태가 다르게 보이지만 조건이 true 일 동안 계속 실행된다는 원리나 동작 방식이 동일하고, 뒤의 두 가지 순환문은 객체의 모든 변수(또는 객체가 가진 자식 객체)에 개별적으로 접근할 수 있는 특징을 가지고 있습니다.
다섯 가지의 순환문이 있음에도 불구하고 뭔가 코드에 관여하여 컨트롤 할 수 있는 부분이 많아 보여서 일까요? 대부분의 초보 개발자들은 for 순환문만 주구장창 사용합니다. 그것도 조건을 조회하는데 i++ 와 같이 정수 i 값을 증가하거나 감소하는 방식만 사용하죠.
그러면 이런 for 문은 어떤가요?
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | var list:Array = [ "a", "b", "c" ]; var i:int; for( init(); hasNext(); ) // 조건절의 모양새에 유의 { trace( getItem( i ) ); } function init():void { i = 0; // some initialize } function hasNext():Boolean { if ( list.length > i ) return true; else return false; } function getItem( $index:int ):* { i++; return list[ $index ]; } |
위의 코드는 유효한 코드 입니다. 반드시 for( i = 0; i < n; ++i ) 의 형태일 필요가 없다는 것이죠. for 문 괄호안의 세미콜론으로 구분되는 세 부분은 왼쪽부터 초기화, 조건절, 루프 후 실행이라는 각각의 역할을 가지고 있습니다. 그런데 for 문은 실제로 가운데의 조건절 부분만 만족하면 앞뒤 부분은 생략되도 문법적으로 에러가 아닙니다. 즉, for( ; hasNext(); ) 이런 for 문 역시 유효합니다.
그러나 이렇게 사용할 바에야 while 문을 사용하는게 퍼포먼스 면에서라도 조금이나마 나을겁니다. 즉, for 문이 while 문에 비해 추가된 기능은 바로 조건절 앞 뒤에 존재하는 부분입니다. for 문은 초기화와 루프 후 실행을 한 줄에 지정할 수 있다는 잇점을 가지고 있습니다. 반대로 초기화할 필요가 없고 루프 후 실행할 것이 없으면 while 문을 사용하는것을 고려해 볼 필요가 있습니다.
* * * * *
A. 문제점 제시
자 그럼 슬슬 순환문 사용에 있어서의 문제점을 살펴볼까요?
초보 개발자들은 for( i = 0; i < n; ++i ) 형태의 순환문만을 사용하려는 습관을 가지고 있는데, 이 습관 때문에 AS2.0에서는 객체들에게 거의 예외없이 "문자열"+숫자 형태의 일련번호를 가진 인스턴스네임이 늘상 사용되어 왔습니다. 이것은 다분히 플래시가 디자이너들에 의해 네비게이션 바를 만드는 툴로 인식되면서부터 습관이 되버린 사용 방법이면서, 동시에 fla 파일을 판매하는 몇몇 사이트에서 네비게이션 바를 만들때 어김없이 사용한 방식이기도 했습니다. 심지어 Flash 8 까지는 숫자만으로 이루어진 인스턴스네임조차도 허용되었기 때문에,[02] 네비게이션 항목 객체의 인스턴스네임이 죄다 숫자로 이루어진 엽기적인 fla 파일들도 한동안 돌아다니곤 했습니다.
그런 네비게이션 바를 만들어낸 사이트들을 탓할 생각은 없습니다. AS2.0 이하의 구조에서는 아주 간단하고 효율적으로 객체를 참조할 수 있는 방법중 하나였으니까 말이죠. 문제는 이런 방법에 익숙해진 디자이너들이 이 방법 이외에는 생각을 하지 않는다는 것입니다.
그럼 그렇게 된 원인을 오랜만에 AS2.0 코드를 보면서 짚어볼까요?
0 1 2 3 4 5 6 7 8 9 10 | // fla 의 상황. 라이브러리에 Linkage 이름을 mc 으로 부여한 무비클립이 있음 var temp:MovieClip; var len:Number = 10; for( i = 0; i < len; ++i ) { temp = this.attachMovie( "mc", "mc" + i, this.getNextHighestDepth() ); temp._x = ( temp._width + 5 ) * i; // 그 밖의 초기화 코드 trace( temp._name ); } |
이렇게 하면 화면에 mc0 부터 for 문이 돌아간 마지막 i 값까지의 객체가 다다닥 생겼을겁니다.

컴파일 결과 화면 상황
이 순환문이 한번 돌아간 이후로는 this 의 어디에서나 mc0, mc1, mc2 … mc9 를 참조할 수 있습니다. 그것인 즉, 인스턴스 객체가 만들어지면서 같은 이름의 인스턴스네임도 부여되었다는 것을 의미 합니다.
이 상황에서 아래와 같은 코드를 실행해보도록 합니다.
0 1 2 | this.mc2._name = "ufx"; // 이렇게 mc2 의 _name 속성을 변경하면 trace( this.mc2 ); // 출력 : undefined trace( this.ufx ); // 출력 : _level0.ufx |
이 코드를 보고 무엇을 알 수 있나요? AS2.0 에서 객체의 인스턴스네임과 _name 속성은 같은것을 지칭한다라는 것을 말해주고 있습니다.
* * * * *
B. 그러나 AS3.0에 와서는 사정이 달라졌습니다.
AS3.0에서는 fla 의 편집 화면상에 존재하는 무비클립에 인스턴스네임을 부여하면, 런타임에 name 속성을 변경할수가 없습니다. name 속성 변경을 시도하면 아래와 같은 에러 메세지를 만날 수 있습니다.
Error: Error #2078: 타임라인에 위치한 객체의 이름 속성은 수정할 수 없습니다.
at flash.display::DisplayObject/set name()
at AS3Test_fla::MainTimeline/frame1()
게다가 코드상에서 new 키워드를 사용하여 라이브러리의 클래스 정의를 사용하여 객체를 생성하는 경우, 인스턴스네임을 임의로 부여할 수가 없습니다.
0 1 2 3 4 5 6 7 8 9 10 | var temp:TagImage; var i:uint; var len:uint = 10; for ( i = 0; i < len; ++i ) { temp = new TagImage(); temp.x = temp.width * i; addChild( temp ); trace( temp.name ); } |
위에서 보는것과 같이 name 속성은 별도로 코딩해서 속성부여하지 않는다면 swf 파일을 컴파일 하는 시점에서 아래와 같이 컴파일러가 자동으로 name 값을 부여하게 됩니다.
trace( temp.name ) 출력 결과
instance1
instance3
instance5
instance7
instance9
instance11
instance13
instance15
instance17
instance19
그렇다면 인스턴스네임은? 알 수 없습니다. 알 수도 없고 지정하거나 수정할 수도 없습니다. 즉, 인스턴스네임을 부여할 수 있는 경우는 fla 의 스테이지 화면에 존재하는 무비클립을 선택한 상태에서 속성 패널을 이용하는 경우로 제한되어 있는 것이죠.
AS3.0과 AS2.0이 가장 확연한 차이를 보이는 것 중 하나가 바로 이 부분 입니다. AS2.0 으로 플래시를 접했던 많은 사람들은 이 부분을 가장 혼동하게 되고, 이렇다는 것을 나중에 알게된 후에는 “정말 불편하게 변경되었잖아” 라고 생각합니다. 모든 무비클립을 인스턴스네임으로 핸들링해 왔는데 갑자기 그것이 제한되니까 그렇게 생각하는것도 당연합니다. 당장 this[ "mc" + i ] 스타일로 인스턴스네임을 줄 수가 없으므로, 뭘 하고 싶어도 할 수 없는 그런 상황이 된 것이죠.
그러나 실제로 인스턴스네임에는 다음과 같은 두 가지 문제가 있습니다.
- 서로다른 객체에게 같은 인스턴스네임을 부여할 수 있습니다. (인스턴스네임이 중복되었는데 에러를 내지 않습니다.)
- 중복된 인스턴스네임을 핸들링하면 먼저생성된 객체만 핸들링됩니다.
이런 부정확성은 객체를 핸들링 하는데 신뢰도를 떨어뜨리게 되어 원하지 않는 결과를 가지고 올 수 있게 됩니다. 그리고 이런 에러는 디버깅 하기도 힘들겠군요.
그래서 AS3.0에서는 인스턴스네임 대신 객체를 핸들링 하는 다른 방법들을 사용하게 됩니다. 그 방법들을 알아보기 전에 다시 한번 생각해보고 넘어가야할 것이 있습니다.
* * * * *
C. 정말 넘버링(Numbering)을 해야만 하는가?
AS2.0시절 인스턴스네이밍을 할때 “mc” + i 스타일로 하는것에 대해서 인데요, 대체 무엇때문에 넘버링을 하는 걸까요?
넘버링을 하는 이유는 두 가지로 볼 수 있습니다. 인스턴스네임이 중복되지 않게 유니크한 값을 가지기 위함이 첫번째 이유이고, 인스턴스네임을 substr() 메서드 등으로 문자열 조작을 하여 숫자부분 만을 획득한 후 그것을 index 로 다른 행동이나 값들을 호출하기 위함이 두 번째 이유 입니다.
그러나 다른 객체와 구분하기 위함이라면 “menu1″ 보다는 “AboutCompany” 가 훨씬 알아보기 쉽잖아요. trace() 찍어볼때는 말할것도 없습니다.
또한 넘버링을 한다는 것은 숫자가 인덱스의 의미를 가져 객체간 구분을 하는 기준을 삼는다는 것을 의미합니다. 그런데 정말 숫자가 의미를 가지고 있습니까? “mc” + i 스타일 네이밍에서 i 값은 단지 객체간 구분을 하고 어떤것을 먼저 생성했는지 순서를 말해줄 뿐, 숫자가 가지는 실제적인 의미가 없습니다.
그러므로 인스턴스네임을 넘버링 하는것에 더 이상 미련을 두지 마세요. 우리는 그 객체의 이름조차 알 필요 없는 더 좋은 방법을 사용하게 될 테니까요.
* * * * *
D. 상황별 해결 방법.
자, 그럼 다음의 세 가지 방식의 솔루션을 제시합니다. 경우에 따라서 특정한 상황에는 반드시 특정한 방법을 사용해야만 할 수 있습니다만, 대체로 여러분의 입맛에 맞는 방법을 사용하면 됩니다.
D-1. AS2.0 방식으로 사용하기를 원한다. (name 속성을 인스턴스네임 대신 사용)
0 1 2 3 4 5 6 7 | var item:MenuItem; var i:int, len:int = 5; for( i = 0; i < len; ++i ) { item = new MenuItem(); item.name = "item" + i; // 이렇게 name 속성에 넘버링 addChild( item ); } |
위와같이 객체들을 생성했으면,
0 1 2 3 4 | var item:MenuItem = getChildByName( "item1" ) as MenuItem; item.doSomething(); // 물론 DisplayObject 수준의 속성을 제어하는 거라면 간단하게 아래와 같이 해도 됩니다. getChildByName( "menu1" ).y = 10; |
위와 같이 DisplayObjectContainer 클래스의 getChildByName() 메서드를 이용해 name 속성으로 객체를 잡아낼 수 있습니다.
D-2. 배열(Array)에 넣어라
그러나 name 속성은 인스턴스네임과 마찬가지로 서로 다른 객체가 동일한 name 을 가지는것이 허용됩니다. 객체를 생성할때야 “이런게 헷갈릴리가 없어” 라고 생각하지만, 우리… 평생 네비게이션만 만들거 아니잖아요. 엔터프라이즈급의 복잡한 시스템을 가진 플래시 애플리케이션이라면 name 속성이 중복되는 일이 보기 드문 일도 아닙니다.
그래서 보통 이런경우 플래시 개발자들은 가장 손쉬운 방법으로 배열을 사용합니다. 우리가 제어하고 싶어하는 일련의 비슷한 객체들은 배열에 넣어서 관리하는 것이 가장 손이 덜 가고 편리한 방법 입니다.
0 1 2 3 4 5 6 7 8 | var itemList:Array = []; var item:MenuItem; var i:int, len:int = 5; for( i = 0; i < len; ++i ) { item = new MenuItem(); itemList.push( item ); // 배열에 push() addChild( item ); } |
위와같이 객체 생성 시점에 배열에 넣어두고
0 1 2 3 4 | var item:MenuItem = itemList[ 1 ]; item.doSomething(); //배열 원소는 실제 객체를 참조하고 있기 때문에 별도의 캐스팅 없이 간단하게 아래와 같이 사용할 수도 있습니다. 단, 개발환경에 따라 코드힌트를 받지 못할수도 있습니다. itemList[ 1 ].y = 10; |
위와같이 배열 연산자로 각 객체를 참조할 수 있습니다.
D-3. Object에 넣는것은 좀더 세련된 방법
Object 클래스는 모든 클래스의 원형 클래스이기 때문에 이런저런 제한이 가장 덜 걸려 있는 클래스 입니다. 제한이 별로 없는 반면 할 수 있는 일역시 별로 없기도 하죠. 시각적인 면만을 본다면 Object 객체는 실제로 스테이지에 보이게 할 수 있는 것도 아니고 추상적인 특성을 가지고 있기 때문에 그리 쓸모가 없어 보이기도 합니다만, 반대로 이러한 유연한 특성 때문에 데이터를 저장하고 읽어내는데 편리한 클래스 입니다.
0 1 2 3 4 5 6 7 8 9 | var itemList:Object = new Object(); var item:MenuItem; var i:int, len:int = 5; for( i = 0; i < len; ++i ) { item = new MenuItem(); item.x = item.width * i; addChild( item ); itemList[ "id" + i ] = item; } |
이렇게 생성한 후에는,
0 1 | trace( itemList.id1 ); // 출력 : [object MenuItem] itemList.id1.y = 100; // 이렇게 속성에도 자유롭게 접근됩니다. |
다른 방법들보다 훨씬 직관적인데다가 간편하게 사용할수 있습니다.
이런 기능은 정확하게는 Object 클래스가 dynamic 으로 정의되어 있기 때문에 가능한 것인데, 반드시 Object 클래스가 아니더라도 dynamic 으로 정의되어 있는 MovieClip 과 같은 클래스도 동일하게 사용할 수 있습니다. 다만, 변수와 값을 보관하는데 MovieClip 씩이나 사용할 필요가 없겠죠. 게다가 이런 용도로 이미 많은 개발자들이 Object 를 사용하고 있기 때문에 코드 가독성을 고려해 봤을때 플래시 네이티브 클래스 중에서는 Object 클래스가 가장 좋은 선택이라고 할 수 있습니다.
* * * * *
E. for each .. in 을 이용한 순환문의 활용
지금까지 객체들을 생성하고 특정한 방식에 의해 세팅하는것을 살펴봤습니다. 이렇게 세팅하는것을 설명한 이유는, 활용을 할때 제대로 활용하기 위함이죠.
위에서 제시한 방법 중 getChildByName() 을 제외한 나머지 두 가지 방법은 객체들을 목록(컬렉션)으로 받게 됩니다. 이런 경우 for each .. in 순환문을 사용하게 되면 훨씬 신뢰성이 좋은 순환문을 만들 수 있습니다.
아래 코드는 for each .. in 순환문의 특성을 명확하게 표현하기 위해, 파싱된 xml 객체를 이용했습니다.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | var xml:XML = <data> <menu> <name>첫번째 메뉴</name> <url>path/myurl_1.html</url> <target>_self</target> </menu> <menu> <name>두번째 메뉴</name> <url>path/myurl_2.html</url> <target>_self</target> </menu> <menu> <name>세번째 메뉴</name> <url>path/myurl_3.html</url> <target>_blank</target> </menu> </data>; var itemList:Array = []; var item:MenuItem, node:XML, i:int; for each( node in xml.menu ) { item = new MenuItem(); //item.updateXml( node ); // 이런식으로 XML 을 객체로 넘겨 내부에서 url 등을 처리하도록 함 i = node.childIndex(); // index 값이 필요하면 xml 의 childIndex() 를 사용 item.x = item.width * i; item.txtName.text = item.name = node.name; addChild( item ); itemList[ i ] = item; trace( item.name ); } |
이런 예제는 실무에 사용되는 코드와 거의 비슷하다고 할 수 있겠죠. xml 을 이용해 for each .. in 순환문을 사용하는 경우 xml 의 노드 순서대로 순환문이 돌기 때문에 순서대로 배열에 들어가게 됩니다.
배열에 예쁘게 들어가있기 때문에 사용하는것도 매우 편리합니다.
0 1 2 3 4 5 | var item:MenuItem; for each( item in itemList ) { trace( item.name ); item.doSomething(); } |
실제로 for each .. in 순환문은 for( i = 0; i < len; ++i ) 스타일의 for 순환문에 비해서 훨씬 직관적으로 사용할 수 있고, 순환 조건 평가가 undefined, NaN 또는 null 이 대입되서 무한루프에 빠지는 경우가 발생하지 않아 에러 발생이 획기적으로 줄어듭니다. 정확히 필요한 만큼만 순환하고 알아서 루프를 끝내기 때문이죠. 또한 속도 테스트를 해봐도 for 순환문보다 약간 빠릅니다.
그런데 한 가지 주의할 점이 있습니다. 배열의 경우 index 0번부터 순서대로 for each .. in 이 돌지만, 저 위의 경우와 같이 Object 에 변수로 저장한 경우에는 순서를 보장해주지는 않습니다. Object 를 컬렉션으로 사용하는 경우에는 실행 순서가 관계없는 순환문에 한정해서 사용해야 합니다.
* * * * *
F. 그런데 코딩하다보면 index 가 필요하던데?
먼저 객체간의 index 가 정말 필요한가 다시 생각해볼 필요가 있습니다. for each .. in 순환문은 컬렉션의 모든 변수(또는 원소)를 순환하기 때문에 index 가 필요하지 않습니다. 만약 여러분이 순환문만을 루프 시키기 위한, i++ 를 생각하고 있다면 더이상 i 를 사용할 필요가 없습니다.
그런데 객체간의 index 값이 필요할 때가 있긴 있습니다. 가장 손쉽게 떠오르는 경우는 객체의 width 속성을 i 로 곱해서 일렬로 주욱 나열하고 싶을 때가 해당하겠죠. 그런 경우에는 컬렉션의 여러가지 index를 활용할 수 있습니다.
F-1. 별도의 변수 index++ 를 사용.
보통의 for 문을 순환시키는 것과 동일한 테크닉입니다.
0 1 2 3 4 5 6 7 | var item:MenuItem; var i:int = 0; for each( item in itemList ) { item = new MenuItem(); item.x = item.width * i; i++; } |
F-2. XML 노드는 childIndex()
XML 노드를 순환할 경우에는 저 위쪽에서 이미 본 것과 같이 childIndex() 메서드를 사용하는 방법도 있습니다.
0 1 2 3 4 5 6 7 | var item:MenuItem; var node:XML, i:int; for each( node in xml.menu ) // XML 을 순환하고 있음에 유의 { item = new MenuItem(); i = node.childIndex(); item.x = item.width * i; } |
F-3. Array 는 indexOf()
배열의 경우라면 indexOf() 메서드가 있겠죠.
0 1 2 3 4 5 6 7 8 | var itemList:Array = []; // 배열에 객체 생성하고 넣는 과정 코드는 생략 var item:MenuItem; for each( item in itemList ) // 배열을 순환하고 있음에 유의 { i = itemList.indexOf( item ); item.x = item.width * i; } |
F-4. Object는 변수에 넘버링.
Object는 위에서 이미 설명한대로, 순서가 보장되지 않으므로, 변수명에 넘버링을 하는 방법을 택하는것이 좋습니다.
0 1 2 3 4 5 6 7 8 9 10 11 | var itemList:Object = new Object(); // 객체 생성하고 Object에 넣는 과정 코드는 생략 // Object 내부에 생성된 변수명은 item0, item1, ... var item:MenuItem; var i:int; var len:int = 10; // 객체를 생성한 갯수를 저장 (예시) for( i = 0; i < len; ++i ) // for each..in 순환문은 Object 내부의 변수를 순차적으로 순환하지 못하므로 index를 이용해 순환하고 있음에 유의 { item = itemList[ "item" + i ]; item.x = item.width * i; } |
F-5. DisplayObjectContainer는 getChildIndex()
DisplayObjectContainer 의 getChildIndex() 메서드를 이용해서 Sprite 객체에 addChild() 된 자식들의 index 를 이용하는 방법도 생각해 볼 수 있는 방법 중 하나 입니다.
0 1 2 3 4 5 6 7 8 9 | // xml 객체는 생략 var container:Sprite = new Sprite(); var item:MenuItem, node:XML, i:int; for each( node in xml.menu ) // XML 을 순환하고 있음에 유의 { item = new MenuItem(); container.addChild( item ); i = container.getChildIndex( item ); item.x = item.width * i; } |
* * * * *
여기까지 인스턴스네임과 순환문과의 관계 부터, AS3.0 개발 과정에서 만나게 될 수 있는 여러가지 상황에 따른 보다 적절한 순환문의 사용까지 두루두루 살펴봤습니다. 실제 여러분들의 코딩 수준은 천차만별일지라도, 저는 글을 쓸때 여러분을 어느정도 일정한 범위로 특정한 후에 쓰고 있습니다. 그렇지 않으면 이도저도 아닌 이해하기 힘든 글이 되기 쉽상이니까요. 그러나 역시 제 블로그의 대부분의 글은 초보 개발자들에 포커스가 맞춰져 있죠. 게다가 이 글은 좀더 초보 개발자의 시각에서 바라보고 글을 썼습니다. 글의 소재가 그러하였으니까요. ^^
그러나 이렇게 끝내면 이 글이 쉽게 느껴지는 개발자 분들은 섭섭해 하실것 같아, 바로 이어서 속편이 이어지겠습니다.
- for each .. in 순환문은 AS3.0에서 추가되었으므로 AS2.0에서는 사용하지 못합니다. [↑]
- 물론, 현재는 숫자만으로 이루어지거나 숫자로 시작하는 인스턴스네임은 허용되지 않습니다. [↑]
Blog under the Creative Commons Attribution-NoDerivs 3.0 License
8월 30th, 2010 on am 5:47
아 저같이 초보에게는 정말 필요한 정보네요. 순환문을 여러가지로 생각해보게 해주는 좋은 포스트인것 같습니다. ^^
여러가지로 테스트를 직접 한번씩 쳐봐야겠네요 ㅎㅎ
8월 30th, 2010 on pm 12:48
이 내용은 작년부터 쓰려고 마음먹었던 내용인데, 드디어 정리를 하게되었네요.
테스트 해보실때, 대부분은 동작할테지만, 혹시 에러가 있는 부분은 알려주세요.
8월 30th, 2010 on pm 2:28
네 테스트 해보고 문제있거나 궁금한게 있으면 답글 달겠습니다 ^^
8월 30th, 2010 on am 9:49
작업에 있어 늘상 하던 방식으로만 코딩하고 있었는데,
잊고 있던 부분이나 새롭게 알게 된 부분이 많아서 좋네요! *.*
깔끔하게 정리된 강좌 감사합니다. ^_^
8월 30th, 2010 on pm 12:53
네이티브 개발자가 아닌 경우가 많은 플래시 개발자들은 이런 대학교 1학년때 배울법한 내용들을 잘 모르는 경우가 많은것 같습니다. 쓰신대로, 알고는 있지만 (편리함에도 불구하고) 사용하지 않던거라 계속 사용하지 않게 되는 것도 있고 말이죠.
8월 30th, 2010 on am 9:52
“아, 이건 꼭 들어야해!”,, 라고 생각햇지만,
늦게 도착하여 중간쯤 부터 들었습니다 ㅠ
그래도 이글 읽고 나니~ 충~~~~분히 이해가 되는군요!
흐흐흐.. 감사드립니다!!
8월 30th, 2010 on pm 12:57
우리 스터디는 너무 정시에 맞춰 오려는 경향이 있는것 같아. 10분만 일찍 도착한다는 기분으로 출발하면 좋을텐데.
무슨말이야? 하는 생각하시는 다른 분들께… 이 포스트는 PFG스터디 4기의 3회차 발표내용 중 하나 이기도 합니다. ^^
8월 30th, 2010 on am 10:42
잘보고갑니다.ㅎㅎ
8월 30th, 2010 on pm 12:58
네 종종 놀러오세요.
8월 30th, 2010 on am 11:02
세계의 끝님은 항상 알찬내용을 포스팅해주셔서 감사히 보고 있습니다~
여러가지의 방법을 알게되어서 좋아요~
저에게도 님같은 사수분이 계시다면 많이 배우고 발전할텐데 ㅎㅎ
아무도 없는게 아쉽네요 ㅎㅎ
잘보고 배우고 갑니당~^^
감사해요~!
8월 30th, 2010 on pm 1:10
초보때 제대로 된 사수의 존재가 개발자의 인생을 좌우하죠. 저 역시 사수 없이 독한한터라 여기저기 구멍뚫린 부분이 많습니다. ^^
8월 30th, 2010 on pm 3:06
잘 읽었습니다.
딴지를 하나 걸자면, F-4 코드의 8번줄 맨 앞쪽에 i가 아니라 item이겠네요
8월 30th, 2010 on pm 4:14
감사합니다. 에러가 있었네요.
그리고, Object 객체는 내부 변수를 순차적으로 순환하지 못하므로(본문에 써 있죠) for each..in 을 사용하는 것에서 for 문의 index 방식으로 바꾸었습니다. ^^
8월 30th, 2010 on pm 3:56
흠… 대학교 2학년때 배웟던게 생각이나네요.
저도 최근 솔루션 제작시에 for문을 막썻다가 인스턴스네임에 대한 문제에서
막막하다가 결국엔 배열에 넣어서 사용하는것으로 하였었습니다. ㅎㅎ
다시한번 되새기게되어 참 좋네요 ^ㅡ^ 감사합니다.
8월 30th, 2010 on pm 4:18
네, 배열에 넣어 컬렉션을 관리하는 방법도 무난하고 신뢰도 높은 좋은 방법입니다.
8월 31st, 2010 on am 11:04
책한권 쓰셔야 할듯요 ㅎ
8월 31st, 2010 on pm 2:05
하핫. 네 감사합니다.
8월 31st, 2010 on pm 2:36
저도 요즘 순환문을 보다 좋게사용할순 없을까 하고 생각하던차였는데
이렇게 좋은글을 읽게되내요^^
많이 배워갑니다^^
9월 1st, 2010 on pm 12:52
제대로 사용하면 높은 생산성을 얻을 수 있죠. ^^
9월 9th, 2010 on am 3:10
인스턴스네임이 죄다 숫자로 이루어진 엽기적인 …
CS3부터 왜 숫자 인스턴스네임은 안되는거야!
이러면서 ["img"+i]가 해결책이라고 생각했었어요
(…이렇게 멋진 포스팅을 그냥 지나칠 수 없기에 덧글남겨요 ㅋ)
9월 9th, 2010 on am 11:05
네. AS3.0에서 객체에 넘버링을 하는건 대부분의 경우에 별로 의미 없는 행위라고 할 수 있습니다. 애초에 attatchMovie()와는 달리 new ClassName() 할때 인스턴스네임을 지정할 수 없으니까 말이죠. ^^
9월 30th, 2010 on am 9:28
이런 ㅠㅠ;; 정말 감사합니다. 이런 좋은 글을 보게 될 줄은 흐흑;;
에프원 형님도 않 알려주시는 깨알같은 정보 감사합니다.
세계의끝님은 복받으실거에요 ㅎㅎ;;
저도 열심히 해서 꼭 님처럼 배푸는 사람이 되겠습니다 ^^
9월 30th, 2010 on pm 4:30
네 꼭 실천하세요.
사실은 저도 실천하고 있는 중인겁니다. ^^
10월 1st, 2010 on am 10:11
오웃 정말 좋은 글이군요~ 책한권 내셔도 될거 같슴당~
많이 배우고 가네여~ 매주 들러야 것네여~ ㅎㅎㅎ~ 감솨합니다. ~^^
10월 3rd, 2010 on am 3:42
최근에는 글이 자주 포스팅 되는건 아니기 때문에 rss 를 등록하시는 것을 추천합니다. ^^
10월 3rd, 2010 on pm 1:41
이, 이건 혁신입니다!
내가 지금껏 넘버링을 왜했지?
10월 5th, 2010 on am 11:44
애초에 AS3.0에서는 인스턴스네임의 사용이 상당히 제한되어 있고, name 속성은 중복이 될 수 있다는 점이 있으므로, 아예 (인스턴스)네임과 관계 없는 방법을 사용하는게 올바른 방법인거죠. ^^
10월 5th, 2010 on am 11:17
배울점 많네요. 다만 손에 익지않아서 불편할뿐이네요.
살짝의 귀차니즘과함께 ㅎ
감사합니다.
ps
Object가 연관배열형태인거죠??
10월 5th, 2010 on am 11:53
처음 보면 코딩이 어색할 수도 있는데, 사용하다 보면 훨씬 가독성이 높고 직관적이라는걸 알 수 있습니다.
itemList 내부(in)의 item 을 각각(each) 순환하라(for)
이렇게 잘 읽히는 코드도 드물죠.
그리고 Object 는 연관배열 형태로도 사용할 수 있습니다. 아래 링크를 참고하세요.
http://help.adobe.com/ko_KR/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7eea.html
11월 29th, 2010 on pm 2:44
저도 실무를 하고 있지만
정말이지 쥔장님 글을 볼때마다
엄청난 내공을 느끼고 갑니다..
앞으로도 이런 금쪽같은 정보 부탁드립니다
감사합니다.^^
11월 29th, 2010 on pm 7:14
이번주에 객체 재사용에 관한 3연속 포스팅 이어집니다 ^^
7월 27th, 2011 on pm 8:29
위에서 Array 에 복제된 인스턴트의 네임을 push로 넣었는데요
그러면 집어넣었던것들을 지우려면 어떻게 하지요?
무비클립이 사라진다고 따라서 사라질것 같지는 않은데..
7월 27th, 2011 on pm 11:50
먼저, 질문 내용과는 직접 관련 없지만 짚고 넘어갈 것이 하나 있습니다.
“복제”되었다고 표현하셨지만 실제로는 new 연산자를 이용해서 “생성”하신 걸겁니다.
그리고 무비클립이 어떻게 사라진것인가 하는 전제조건이 필요합니다.
어차피 그래봐야 기껏 무비클립은 removeChild() 되고 null 이 대입되는게 전부기 때문에, 실제 메모리에서 사라지는 것은 가비지 컬렉션이 돌고 난 이후가 되겠죠.
어쨌건 배열에 push 한 객체를 없앤것이 아니라 객체를 가리키고 있는 변수를 해제한 것에 불과하므로, 여전히 객체도 보이지는 않지만 남아 있습니다. 배열 원소도 온전히 그 객체를 가리키고 있죠.
그러므로 배열 원소에 undefined 나 null 을 대입해 주거나 pop(), slice() 등의 메서드로 처리해줘야 합니다.