[CS4] 플래시 플레이어 디버거 버전 참고

보통 플래시 콘텐츠를 개발을 할 때, 많은 개발자들이 플래시 플레이어 디버거버전을 설치하여 사용하고 있다. 이유는 개발자가 미처 예상하지 못한 버그나 에러를 확인 하기 위해서 사용한다.

물론 개발자도 사용자인지라 웹서핑 중에 에러창을 확인 해야하는 짜증을 감당하지 못하고 일반 플래시플레이어 버전을 사용하는 개발자도 많은 것 같다. 사실 디버거버전은 개발자들을 위해 엄격한 런타임 환경을 제공하는 것이기 때문에 일반 사용자 환경으로 고려해야하는 대상은 아니라고 할 수 있다. 하지만 다른 개발자들에게 보여질 에러화면을 생각하면 개발자로써 포기할 수 없는 문제이다.

일전에 진행했던 프로젝트에서 예상하지 못한 문제로 골머리를 앓았던 적이 있다. 문제는 이러하다.

컨테이너가 되는 플래시에서 개별적인 컨텐츠 플래시를 로드하여 사용한다. 개별적인 컨텐츠에 해당하는 플래시들은 타임라인에 몇 줄의 코드만 삽입하면 되기 때문에 특별히 document class를 할당하지 않았다. 이런 상태에서 컨테이너에서 개별 플래시들을 로드하여 사용할 경우, 일반 플래시 플레이어에서는 문제가 없지만 디버거 버전에서는 처음 로드한 컨텐츠는 문제가 없으나 이후에 로드하는 컨텐츠에서는 문제가 발생한다.

디버거버전에서는 초기에 로드한 객체를 unload하더라도 이후에 로드하는 플래시가 독립된 document class명이 없다면 기존의 객체로 간주하고 기존 객체가 unload되면서 새로 로드된 객체의 참조 마저도 잃어버리는 현상이 나타난 것이다.

물론 컨테이너에서 로드하는 개별 플래시 내부의 함수를 호출하는 형태이기 때문에 엄밀히 말하면 플래시 플레이어에서 권장하는 설계는 아니다. 그러나 구조상 퍼포먼스를 높이기 위해서는 어쩔 수 없는, 나름대로의 선택이 있었다.

그래서 어쩔수 없이 개별 컨텐츠에 해당하는 플래시에 모두 가상의 document class를 설정하는 것으로 해결했지만 만약에 로드되는 플래시가 기존에 사용했던 document class와 동일한 class명을 사용할 경우 문제가 발생할 여지가 있다.

엄밀히 말하면 동일한 패키지, 네임스페이스 영역 내에 있기 때문에 문제가 발생할 수 밖에 없겠지만 이 하나의 문제로 인하여 유지보수의 복잡성이 증가한 문제는 나에게 무엇을 포기해야 하는가라는 고민을 하게 했다.

결론적으로 디버거버전에서의 문제는 심각한 수준이었기 때문에 플래시플레이어 디버거 버전의 성질을 건드리지 않는 쪽으로 일단락 되었다.

iPhone 에서 작성된 글입니다.
신고
    

설정

트랙백

댓글

[CS4] Flash10에서 추가된 Loader 객체의 unloadAndStop 메소드

function unloadAndStop(gc:Boolean = true):void

기존에 unload 메소드의 경우 load 메소드를 사용하여 로드된 Loader 객체의 자식을 제거할 수 있었으나 해당 자식이 다른 객체로부터 참조가 남아 있을 경우에는 메모리상에서 완전히 제거할 수 없었다. 따라서 부모 swf에서 또 다른 자식 swf를 로드할 경우, Event.UNLOAD 이벤트를 받아서 unload가 발생할 때 남아있는 스트림을 닫거나 이벤트 리스너를 일일히 제거해줘야 하는 개발자의 부담이 있었다.

구현된 형태가 복잡할 경우 사실상 완전하게 제거하는 것이 불가능할 정도다. 이로 인해서 참조가 남아 있을 경우, 메모리 리스크가 발생하고 남아 있는 객체에서 프레임이 돌고 있는 상황이라면 결과적으로 CPU 사용량도 계속적으로 쌓이게 되는 문제가 있었다.

이러한 문제를 해결하기 위해서 Flash10버전에서는 Loader 객체에 unloadAndStop 함수가 추가 되었는데 unloadAndStop함수는 unload로 완전하게 제거할 수 없었던 자식의 참조를 삭제하여 메모리가 쌓이는 현상을 해결할 수가 있다. 아래는 플래시 도움말에 있는 내용이다.

/////////////////////////////////////////////////
unloadAndStop () 메서드  
flash10 function unloadAndStop(gc:Boolean = true):void
언어 버전:  ActionScript 3.0
런타임 버전:  AIR 1.0, Flash Player 9

자식 SWF 파일 내용을 언로드하고 로드된 SWF 파일의 명령 실행을 중지합니다. 이 메서드는 자식 SWF 파일의 EventDispatcher, NetConnection, Timer, Sound 또는 Video 객체에 대한 참조를 제거하여 Loader.load() 또는 Loader.loadBytes()를 사용하여 로드되고 있는 SWF 파일을 언로드합니다. 따라서 자식 SWF 파일 및 자식 SWF 파일의 표시 목록에서 다음 동작이 발생합니다.

•사운드가 중지됩니다.
•Stage 이벤트 리스너가 제거됩니다.
•enterFrame, frameConstructed, exitFrame, activate 및 deactivate의 이벤트 리스너가 제거됩니다.
•타이머가 중지됩니다.
•Camera 및 Microphone 인스턴스가 분리됩니다.
•무비 클립이 중지됩니다.

매개 변수
gc:Boolean (default = true) — 자식 SWF 객체를 대상으로 가비지 수집기를 실행할지 여부(true 또는 false)를 나타내는 힌트를 제공합니다. 여러 객체를 비동기적으로 언로드하는 경우 gc 매개 변수를 false로 설정하면 응용 프로그램 성능이 향상될 수 있습니다. 그러나 이 매개 변수를 false로 설정하면 자식 SWF 파일의 미디어와 표시 객체가 unloadAndStop() 명령을 실행한 후에도 메모리에 유지될 수 있습니다.
/////////////////////////////////////////////////

이 메소드를 이용하면 그 동안 swf로드하는 과정에서 발생했던 메모리 리스크는 어느 정도 해결 할 수가 있게 되었다.

신고
    

설정

트랙백

댓글

즐거운 만남 두 번째 이야기

액션스크립트까페에서 주관한 2차 컨퍼런스가 Adobe의 후원으로 강남 교보타워에서 열렸다. 하반기에 일복이 터져 준비를 제대로 하지 못하고 소통을 한 것 같아서 아쉬웠던 시간 이었다. 짧은 시간에 많은 것을 공유하고자 했던 것이 오히려 많은 분들에게 도움이 되지 않은 것은 아닌지 약간 걱정이 되기도…

항상 좋은 자리를 마련해주시는 땡굴이형님과 스탭분들 준비하시느라 고생 많으셨습니다. 특히 바쁜 업무에도 주어진 시간을 멋지게 소통하신 블랙키즈님, 언노운님, 땡굴이형님 고생 많으셨습니다. 그리고 황금 같은 주말을 반납하고 오래도록 자리를 빛내주신 참가자분들도 고맙고 반가웠습니다.






출처 : 마넴이리님

출처 : 마넴이리님



다음에 또 기회가 있다면 저에게 주어진 시간을 효율적으로 사용해 보도록 하겠습니다. 항상 아쉬움이 남네요 ^^;
감사합니다.

신고
    

설정

트랙백

댓글

[CS4] Vector의 이해

FlashCS4(FlashPlayer10) 버전에서 지원하고 있는 Vector 객체에 대해서 정확히 무엇이며 어떤 역할을 하는지에 관한 자료를 정리하는 차원에서 이야기 해 볼까 한다.

일단 아래는 FlashPlayer10 레퍼런스 문서에 있는 Vector에 관한 기본 내용이다.











----------------------------------------------------------------
Vector 클래스를 사용하면 벡터에 액세스하고 이를 조작할 수 있습니다. 벡터는 요소의 데이터 유형이 모두 같은 배열입니다. 요소의 데이터 유형을 Vector의 기본 유형이라고 합니다. 기본 유형은 내장 클래스 및 사용자 정의 클래스를 포함한 모든 클래스일 수 있습니다. 기본 유형은 Vector 변수를 선언할 때 및 클래스 생성자를 호출하여 인스턴스를 만들 때 지정됩니다.

Array와 마찬가지로 배열 액세스([]) 연산자를 사용하여 Vector 요소의 값을 설정하거나 검색할 수 있습니다. 또한 몇 가지 Vector 메서드를 통해 요소 값을 설정 및 검색하는 메커니즘이 제공됩니다. 이러한 메서드로는 push(), pop(), shift(), unshift() 등이 있습니다. Vector 객체의 속성 및 메서드는 Array의 속성 및 메서드와 비슷하며 대부분의 경우 동일합니다. 사용하는 Array의 모든 요소가 같은 데이터 유형인 경우 항상 Vector 인스턴스를 사용하는 것이 좋습니다.

Vector의 기본 유형은 접미사 유형 매개 변수 구문을 사용하여 지정됩니다. 유형 매개 변수 구문은 다음 예제와 같이 마침표(.), 여는 각괄호(<), 클래스 이름, 닫는 각괄호(>) 순서로 구성됩니다.

var v:Vector.<String>;
 v = new Vector.<String>();

예제의 첫 번째 행에서는 변수 v를 Vector.<String> 인스턴스로 선언합니다. 즉, 이 변수는 String 인스턴스만 포함할 수 있으며 String 인스턴스만 검색할 수 있는 Vector(배열)를 나타냅니다. 두 번째 행에서는 동일한 Vector 유형(요소가 모두 String 객체인 Vector)의 인스턴스를 생성하여 v에 할당합니다.

Vector.<T> 데이터 유형으로 선언된 변수에는 같은 기본 유형 T로 생성된 Vector 인스턴스만 저장할 수 있습니다. 예를 들어 new Vector.<String>()을 호출하여 생성된 Vector를 Vector.<int> 데이터 유형으로 선언된 변수에 할당할 수는 없습니다. 기본 유형은 정확히 일치해야 합니다. 예를 들어 다음 코드에서는 객체의 기본 유형이 변수의 선언된 기본 유형과 다르므로 코드가 컴파일되지 않습니다. Sprite가 DisplayObject의 하위 클래스이지만 결과는 마찬가지입니다.

// This code doesn't compile even though Sprite is a DisplayObject subclass
 var v:Vector.<DisplayObject> = new Vector.<Sprite>();

기본 유형이 T인 Vector를 T의 수퍼 클래스의 Vector로 변환하려면 Vector() 전역 함수를 사용합니다.

Vector 클래스에는 데이터 유형 제한뿐만 아니라 Array 클래스의 경우와 다른 몇 가지 제한이 더 있습니다.

    * Vector는 밀착형 배열입니다. 1에서 6 사이의 위치에 값이 없어도 인덱스 0과 7에 값이 있을 수 있는 Array와 달리 Vector의 경우에는 모든 인덱스에 값 또는 null이 있어야 합니다.
    * Vector는 고정 길이일 수도 있습니다. 즉, 포함된 요소 수를 변경할 수 없을 수 있습니다.
    * Vector의 요소에 액세스할 때는 경계가 검사됩니다. 마지막 요소(length - 1)보다 큰 인덱스에서는 값을 읽을 수 없습니다. 현재 마지막 인덱스를 벗어난 인덱스에는 값을 설정할 수 없습니다. 즉, 기존 인덱스나 [length] 인덱스에만 값을 설정할 수 있습니다.

이러한 제한 사항으로 인해 Vector에는 모든 요소가 단일 클래스의 인스턴스인 Array 인스턴스보다 두 가지 우수한 점이 있습니다.

    * 성능: Vector 인스턴스를 사용하면 Array를 사용할 때보다 훨씬 빠르게 배열 요소에 액세스하고 반복할 수 있습니다.
    * 유형 안전: 엄격 모드를 사용하면 Vector에 잘못된 데이터 유형의 값을 할당하거나 Vector에서 값을 읽을 때 잘못된 데이터 유형을 사용하는 등의 데이터 유형 오류를 컴파일러에서 식별할 수 있습니다. 그러나 push() 메서드나 unshift() 메서드를 사용하여 Vector에 값을 추가할 때는 인수의 데이터 유형이 컴파일 타임이 아닌 런타임에 검사됩니다.
----------------------------------------------------------------

Array와 Vector
Vector는 ECMAScript4에서 도입된 기능으로 이번 FlashPlayer10에서도 적용이 되었다. 모든 요소가 동일한 객체를 포함해야 한다는 제약이 따르지만 위 레퍼런스의 내용과 같이 Array 배경보다 몇 가지 장점을 가지고 있다. 속도와 엄격한 유형검사가 그것이다.

Vector는 Array와 같이 Object를 확장하며 dynamic 클래스 이지만 Array와 같이 정의되지 않은 프로퍼티에 값을 할당할 수는 없다. 예를 들어

var arrStr:Array = new Array();
arrStr.name = "jasu";
trace(arrStr.name);

이런 형태로 실행을 하면 arrStr에 있는 name 속성을 런타임에서 생성하여 값을 참조할 수 있다. 하지만 Vector의 경우 컴파일에서 에러를 throw 한다.

var vecStr:Vector.<String> = new Vector.<String>();
vecStr.name = "jasu"; // error 1119: Access of possibly undefined property name through a reference with static type __AS3__.vec:Vector.<String>.
trace(vecStr.name);


Vector의 연속된 배열과 고정 길이
var arrStr:Array = new Array();
arrStr[0] = "100";
arrStr[1] = "200";
trace(arrStr[1]); // 정상적으로 컴파일 됨.

var vecStr:Vector.<String> = new Vector.<String>(2, true);
vecStr [0] = "100";
vecStr [1] = "200";
vecStr [2] = "300"; // vecStr의 고정된 길이(2) 값을 벗어난 인덱스 참조로 에러 발생
trace(vecStr[2]);

var vecStr:Vector.<String> = new Vector.<String>(2, false);
vecStr [0] = "100";
vecStr [1] = "200";
vecStr [2] = "300";
trace(vecStr[2]); // 정상적으로 컴파일 됨.

Vector의 constructor 첫번째(length), 두번째(fixed) default 값은 0과 false이다.


Vector에서 push 메소드의 암묵적 형 변환
var vetStr:Vector.<int> = new Vector.<int>();
vetStr[0] = true; // TypeError 발생
trace(vetStr[0]);

var vetStr:Vector.<int> = new Vector.<int>();
vetStr.push(true);
trace(vetStr[0]); // output 1 (push 메소드 실행시 암묵적으로 할당된 값의 형을 강제 변환함.

Vector의 push 시에도 Type 체크를 하여 TypeError를 throw 해주는 것이 좋을 것 같으나 현재 Vector의 경우 push로 값을 넣을 경우 암묵적으로 강제 형 변환을 하고 있다.

정리
Vector의 경우 기존에 사용하는 문법과 약간은 다른 형태를 취하고 있기 때문에 처음 접할 때는 생소하다. 하지만 기존에 사용하던 방식 “:객체명”에서 :객체명.<단일형> 으로 추가하되, 그 Vector에는 포함하고자 하는 형태만 사용한다는 것을 머리 속에서 명확하게 인지한다면 기존에 Array를 사용하여 생기던 속도 문제와 에러를 예방할 수 있다는 차원에서 좀더 명확하고 빠른 알고리즘을 작성할 수 있지 않을까 싶다.



신고
    

설정

트랙백

댓글

웹에서 컴파일하는 서비스 Wonderfl

Kayac의 Wonderfl 서비스가 재미있다. 웹페이지 상에서 ActionScript를 작성하는 순간 일정 시간에 작성한 ActionScript 코드를 실시간으로 컴파일을 하여 오른쪽에 결과물을 swf로 보여준다. FlashPlayer10 버전의 코드도 제대로 컴파일 되는 것 같다. 이런 것을 보면 앞으로 웹에서 돌아가는 플래시툴도 개발 가능할 것으로 보인다.











신고
    

설정

트랙백

댓글


티스토리 툴바