어디엔가 있을나의 한 쪽을 위해헤매이던 숱한 방황의 날들,태어나면서 이미누군가가 정해졌었다면,이제는 그를만나고 싶다.
'쫑군의 New World'에 해당되는 글 56건
- 2009/09/16 kineticroad 홀로서기
- 2009/09/05 kineticroad ActionScript의 대기코드?
- 2009/08/29 kineticroad 삶이 비극인 이유
- 2009/08/25 kineticroad Flash player 메모리 관리 Tip
- 2009/08/25 kineticroad 행복을 찾아서(The Pursuit Of Happyness)
- 2009/04/19 kineticroad URLStream 사용기
- 2009/04/19 kineticroad 오랜만의 블로깅? AIR File.ApplicationDirectory 접근하기.
- 2009/03/18 kineticroad every beat of my heart
- 2009/03/02 kineticroad 장래희망
- 2009/01/30 kineticroad 아..나 눈물좀 닦고
순차적으로 실행하지 않아서 통신해서 뭔가 불러올때 대기하지 않고 바로 다음 코드를 실행해서 오류가 난다. 해결 방법이 없을까?
package
{
import mx.rpc.http.HTTPService;
import mx.events.ResultEvent;
public class DataConnection extends HTTPService
{
/**
* Constructor.
*/
public function DataConnection()
{
// super class Constructor.
super();
eventConfiguration();
send("http://www.test.com/callData.php");
}
public var totalDataLength:int = -1;
private function eventConfiguration():void
{
addEventListener(ResultEvent.RESULT, resultHandler);
}
public function getTotalDataLength():int
{
return totalDataLength;
}
private function resultHandler(event:ResultEvent):void
{
totalDataLength = event.result.totalDataLength;
}
}
}
private function test():void
{
var connection:DataConnection = new DataConnection();
var i:int = connection.getTotalDataLength();
trace(i);
}
Life's Tragedy is that we get old too soon and wise too late삶이 비극인 것은, 우리가 너무 일찍 늙고 너무 늦게 철이 들기 때문이다.
사람들은 옷을 입은 채로는 바닷물에 빠지지 않은 것이 인생이라고 생각하지만옷을 입은 채 바닷물에 빠지는 것도 인생이죠.마음 속에 금지를 가지지 말아요.생은 그렇게 인색한게 아니니까.
Flash player 의 오랜 과제였던 메모리 관리 문제는 어떤 프로젝트를 진행하던지 간에 언제나 이슈로 대두 되었다.
특히나 Flex 내에서 모듈을 load하고 unload하는 과전에 있어서 메모리의 계속된 증가는
결국 사용자 PC의 브라우져가 과도한 메모리 점유로 인해 온갖 문제들을 야기 시켰는데
그것은 종국에 가서 클라이언트의 불만으로 이어지고
그런 불만을 해소하기 위해서 System.gc() 메서드나 LocalConnection 을 통한
강제 garbage collection을 해주고자 하였으나 근본적인 해결책은 되지 못했다.
한편 사람들은 메모리 문제에 대해서 removeListener를 통해 리스너를 삭제하는 방법들을
메모리 점유나 퍼포먼스에 대한 해결책으로 제시하고 있지만
문제는 무한이 늘어나는 인스턴스의 해결은 어찌 하느냐가 관건이었다.
전번 프로젝트를 통해 메모리를 줄여나가는 방법들에 대해서 여러가지로 연구하고
별의 별 방법들을 사용했고 시도했었다.
iframe을 통한 flash player의 브라우져 refresh는 Adobe사에서 권장하는 방법이었으나
다수의 Application의 생성이 불가피하고 rich internet 시장에 맞지 않는 작업들이라
클라이언트의 클래임을 설득하기 위한 회의는 연일 지속되어야만 했다.
게다가 refresh로 인해 Application의 다운로드 속도가 만족되어지지 않을 경우
RSL 방식이니 뭐니 하면서 Application 자체의 용량을 줄이기 위해 전쟁을 해야하는 상황들과 직면해야한다는 사실에는
변함이 없었다.
(그로인한 컴파일러 옵션값 조정에 몇 시간, 혹은 몇일의 시간을 날려먹었는지 모른다.)
프로젝트를 진행함에 있어서 가장 중요한것은 맨 마지막 산출물이 얼마나 rich한 작업이었는 지를
따지기 이전에 메모리의 양을 어찌 조절하느냐가 관건이 되었다.
앞뒤가 거꾸로 돌아가는 것이 아닌가 싶을정도로 고민과 번뇌로 코드를 들여다 봐야했고
메모리 점유율을 낮추기 위해 그리고 왜 낮춰지지 않는가에 대한 고민을 헤아릴 수 없이 해야만 했으며
생머리던 내 머리칼은 어찌나 쥐어뜯었는지 곱슬머리가 되어버렸다면 얼마나 많은 고민을 했을지 예상했으리라
그렇다면 왜 Flash player는 메모리를 낮추지 않을까?
왜 Flash player는 unload된 모듈에 대한 객체들을 지워주지 않을까에 대해 이해에 도움이 되기 위해서는
일단 Flash player 자체는 우리의 생각보다 멍청한 프로그램이고 뭐가 필요한 객체인지 아닌지에 대한
이해가 떨어지기 때문이라고 생각하면 속이 좀 편안해 질거다.
ActionScript에는 강한참조, 약한참조 가 있다는 사실은 조금만 공부해도 알 수 있는 내용이고
addEventListener 메서드로 이벤트를 등록할 때 useWeakReference 옵션 값을 true로 해줘서
약한참조로 만들어주면 gc가 돌때 등록된 이벤트를 같이 삭제한다고 이야기는 들었으나
이 약한참조라는게 어느 순간 목적 객체를 놓치는 경우가 종종 발생하여 문제는 계속해서 발생하게 된다.
(그 놈의 원인모를 문제는 다 여기서 나오는 거더라)
그렇다면 그냥 removeEventListener를 습관화 하는게 가장 좋은 방법이다.
묻지도 말고 따지지도 말고 그냥 무조건 remove시키는게 제일인것으로 결론이 났다.
그리고 가장 큰 문제인 ArrayCollection 의 강한참조가 문제다.
ArrayCollection은 정말 답이없는 객체다.
dataProvider로 DataGird 같은 List 객체나 Chart 객체에 Binding을 걸면 그것또한 낭패.
왜냐하면 ArrayCollection을 List 객체나 Chart객체 내부에선 dataProvider로 참조걸린 객체가 있다면
모듈 삭제시 인스턴스를 삭제 하지 않기때문이다.
한마디로 DataGrid가 삭제되도 내부의 데이터 값 자체는 삭제하지 못한다는 것이다.
이런 낭패가!
이벤트도 다 지웠겠다 UI객체들도 삭제했으니 당연히 메모리는 다시 원상 복구 되겠지!
하고 믿어 의심치 않고 있는 마당에 이런 뒤통수 맞는 경우가;;
Binding이라는게 쓸때는 참 편하고 좋다가도 이런 이유때문에 객체가 그대로 살아서 내 목을 조이고 있다고
생각하면 정말 믿는 도끼에 발등을 찍히는 기분이다.
그래서 UI객체가 삭제되는 시점을 틈타 FlexEvent.REMOVE 이벤트 발생시 객체들을 아래와 같이 삭제한다.
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
[Bindable]
private var tempAC:ArrayCollection;
override protected function createChildren():void
{
super.createChildren();
addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHanlder);
}
private function creationCompleteHandler(evnet:FlexEvent):void
{
removeEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
tempAC = new ArrayCollection([
{data1:"temp1", data2:"temp1"},
{data1:"temp2", data2:"temp2"},
{data1:"temp3", data2:"temp3"},
]);
addEventListener(FlexEvent.REMOVE, removeHandler);
}
private function removeHandler(event:FlexEvent):void
{
removeEventListener(FlexEvent.REMOVE, removeHandler);
Object(dg.dataProvider).removeAll();
tempAC.removeAll();
removeAllChildren();
}
]]>
<mx:DataGrid id="dg" dataProvider="{tempAC}">
<mx:columns>
<mx:DataGridColumn headerText="sample1" dataField="data1" />
<mx:DataGridColumn headerText="sample2" dataField="data2" />
</mx:columns>
</mx:DataGrid>
removeHandler부분을 잘보면 ArrayCollection 객체에 null로 삭제하는 것이 아니라 removeAll() 메서드로 삭제하고 있고 모든 이벤트 들은 사용이 종료되었을 때 그때 그때 삭제해주는 버릇이 중요하다.
그래야 쓸데없는 인스턴스를 줄일 수 있고 나중에 클라이언트와의 언쟁을 조금이라도 줄일 수 있게 되니 서로 간에 스트레스 없이 좋게좋게 끝낼 수 있을 것이다.

2006년도 개봉했던 이 영화는 많은 사람들의 기억에 없을지도 모르겠다.
큰 감동도 없었고 큰 여운도 없는 영화였다.
다만 더럽게 가난하고 더럽게 가난한 그 상황을 이겨내기 위한 한 아버지의 눈물겨운 사투(?)를 그린영화라
더 가슴에 와 닿는건 아닌가 싶었다.
시골에서 올라와 대학도 못나오고 잘 팔리지도 않는 기계나 팔고 다니는 외판원에
자신의 아들을 괜찮은 놀이방에 데려다 줄 수 없어서 차이나 타운의 어떤 싸구려 놀이방에 맡겨야 했고
아내와는 헤어졌으며 250달러로 4주를 버텨낼 수 있을 만큼 가난에 찌들어 사는
어떤 한 남자를 그려낸 이 영화는 OECD 자살률 1위, 청년실업 60만을 넘어선 이 나라에
아주 중요한 메시지를 던져줬다.
그건 어떤 한 장면에서 아들과 아버지가 했던 대화내용.
절대 귀담아 듣지마
아빠 말이라도
알았지?
꿈이 있으면 지켜야 돼
남이 잘되면 배 아픈게 사람 심리거든
원하는게 있으면 어떻게든 쟁취해
절대 귀담아 듣지말라는 아버지의 말이 그토록 가슴아프게 들렸던 이유는 뭘까.
자신의 아내에게 증권 중개인이 될거라고 했더니
그래. 지금의 내겐 말도 안되는 꿈이라고 하고 주변에선 "웃기지 마" 라고 말을 하지만
그 처절하고 지독한 가난 속에서 모든 것을 포기하고 싶었을 때
지하철 화장실에서 자신의 아들과 노숙을 해야했을 때
노숙자 숙소에 누울 자리를 마련하지 못해 눈물을 흘려야 했을 때
그 포기 하지 않았던 그 마음은 그를 증권사 정직원으로 채용되게 했고
모두가 "넌 안될거야"라고 하고 "지금의 너는 할 수 없어"라고 말하지만
결국 어떤 것도 포기하지 않고 내달려 꿈을 쟁취한 한 남자의 이야기.
우리가 보고 배워야 하는건 결국 영화 첫줄기에 했던 그 한마디일것이다.
원하는게 있으면 어떻게든 쟁취해"
꿈을 잃어가는 현대의 청년들을 위한 한마디가 아닐까.
AIR로 웹에 있는 파일에 접근해 FileReference 클래스 이용없이 맞바로 로컬에 파일을 생성해야하는 이슈였는데
이부분은 URLStream클래스로 간단하게 해결할 수 있었다.
private const HOST_NAME:String = "http://www.kineticroad.com/blog";
private var urlStream:URLStream;
private function urlStreamTest():void
{
urlStream = new URLStream();
urlStream.endian = Endian.LITTLE_ENDIAN;
var request:URLRequest = new URLRequest(HOST_NAME + "test.xml");
addEventListeners();
urlStream.load(request);
}
private function addEventListeners():void
{
urlStream.addEventListener(Event.COMPLETE, completeHandler);
urlStream.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
urlStream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
urlStream.addEventListener(ProgressEvent.PROGRESS, progressHandler);
}
private function removeEventListeners():void
{
urlStream.removeEventListener(Event.COMPLETE, completeHandler);
urlStream.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
urlStream.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
urlStream.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
}
private function completeHandler(event:Event):void
{
var remoteData:
var clientFile = new File('D:/test.xml');
var clientStream:FileStream = new FileStream();
clientStream.open(clientFile, FileMode.WRITE);
while(urlStream.bytesAvailable)
{
var value:int = urlStream.readByte();
clientStream.writeByte(value);
}
clientStream.close();
urlStream.close();
}
private function ioErrorHandler(event:IOErrorEvent):void
{
trace("IOError / " + event.type);
}
private function securityErrorHandler(event:SecurityErrorEvent):void
{
trace("Security Error / " + event.sandboxType);
}
private function progressHandler(event:ProgressEvent):void
{
var percent:Number;
percent = Math.round((bytesLoaded * 100) / bytesTotal);
trace(percent + "% complete");
}
아주 간단한 만든 샘플인데 일단 서버의 파일에 접근해서 readByte로 읽어온다. 읽어온 value를 미리 선언해 뒀던 클라이언트 파일에 writeByte로 작성에 넣는 작업을 수행하게 되어있다.
아주 간단하게 구성되어있는 이 소스를 기반으로 여러가지 작업을 할 수 있게 되었는데
대표적으로 모듈단위의 AIR 업데이트를 수행하는 것이나 서버의 이미지 파일을 지정된 위치에
지정한 이름으로 저장할 수 있게 하는 FileReference.browse() 메서드 기능을 구현할 수도 있다.
잘만 만들면 FTP 비슷한 프로그램을 만드는 것도 가능할 것이다.
그도 그럴게 프로젝트다 뭐다 해서 좀 정신이 없었기 때문이기도 하고
시험준비를 하느라고(요새 대학교는 중간고사 시즌이란다;;; 덜덜) 새벽까지 수업듣고 자느라
정신을 챙길래야 챙길만한 여유가 없었기 때문인데 오늘은 AIR 에대한 내용으로 블로깅을 해볼까 한다.
AIR를 처음 만진게 1.0 처음 런칭했을 때였는데(코드명 아폴로로 불렸을 때는 존재를 잘 몰랐었다;;; 아 둔탱이)
그당시 개발을 EditPlus로 하느라 AIR가 어떤식으로 Compile하고 실행하는지 Developer Guide를
하나하나 해석해가며 눈물을 삼겼었던 적이 있었다.(흑.. 추억하고 싶지 않다는;;;)
그때 만들었던게 FXUG Lite였다. FXUG(Flex User Group)는 회사에서 만든 비영리 커뮤니케이션으로
Full Flex로 개발되어 MDI로 구성된 UI를 선보였었다.(개발하는데 무려 3개월이나 걸리긴 했지만;;)
아무튼 FXUG Lite의 기능중 극히 작은 기능이긴 하지만 사용자가 동적으로 화면의 구성을 바꿀 수 있게
마련한 옵션 메뉴가 있었다. 이것은 사용자가 사용자 정보 xml 파일을 읽어봐 수정하고 다시 쓰는 작업을
하게끔 되어있는데 그 때 크게 발생한 이슈가 사용자의 ApplicationDirectory에 있는 파일을 수정하거나
쓸 수가 없었다는 것이다.
보통 프로그램을 설치하게 되면 ApplicationDirectory가 Program Files 디렉토리로 설치가 되는데
그 부분을 Flie.ApplicationDirectory 속성으로 접근해 파일을 다시 쓰게 되면 Security Error를 띄우도록 AIR의 보안정책으로 명시 되어있다.
이를 어찌할까 하다 구글링으로 찾은 꽁수는 어느 중국인의 블로깅을 보고 힌트를 얻었었다.
(한자들 앞에서 무력했었던 끔찍한 기억 작렬 ㅠㅠ)
해결한 방법은 다음과 같다.
var tempFile:File = File.applicationDirectory.resolvePath("test.xml");
tempFile = new File(tempFile.nativePath);
일단 tempFile로 선언된 File 객체에 test.xml 파일에 접근한다. applicationDirectory에 있는 파일에 접근해 정보를 읽는건 보안정책에 어긋나는건 아니니 일단 접근을 하고 새로 File 객체를 생성한다. 물론 instance를 늘리지 않고 기존에 사용했던 tempFile를 다시 생성하는데 이때 아까 접근했던 test.xml 파일의 nativePath 경로를 인자로 넘겨준다.
이 방법을 이용하면 test.xml 파일을 찾아서 쓰거나 수정할 수가 있는데 이유인즉슨 이렇게 해석될 수 있다.
보안정책상 파일에 applicationDirectory에 속해있는 파일을 수정하거나 쓰는건 안된다. 다시 이야기하면 File 객체로 접근만 하지않으면 된다는 이야기.
그래서 잔머리를 굴린방법이 nativePath다.
applicationDirectory에 접근하긴 했으나 String으로 접근하게 되면 보안정책상 하자가 없다는 이야기다.
Adobe에서는 이런 정책을 수정해서 접근 할 수 없게 하겠다....라고 이야기 했다고는 하나(들리는 풍문에 의하면)
"Adobe가 귀찮아서 안하지 않을까?"라고 조심스럽게 추측하고 있다.(사실 믿고 있다. Adobe)
하지만 이 방법으로도 어려운 난제가 있는데 Vista 이후의 Window는 위의 방법으로도 파일을 쓸 수가 없다.
그 이유는 AIR 의 보안정책에는 하자가 없지만 운영체제 상의 보안정책때문인데 이는 관리자 모드로 프로그램을 실행하게 되면 파일을 쓸 수가 있다.(AIR 자체로는 이를 해결할 방법이 없다;;;
운영체제가 막겠다는데 이겨낼 방법이 있을 수가 없지 않은가;;;
아 물론 XP 사용자는 해당사항이 없다.
For better or worse, till death do us part
기쁠때나 슬플때나 죽음이 우리를 갈라놓을때까지
I'll love you with every beat of my heart.
내심장이 뛰는 그 순간순간마다 당신을 사랑하겠습니다.
그 다음은 과학자에서 천문학자가 되고 싶었다.
초등학교 5학년때 별을 보기 위해 밤새 추운공기에 벌벌 떨면서 북극성과 카시오페아를 관찰하면서 그런 생각을 했다.
그 다음은 만화가가 되고 싶었다.
그림그리는게 좋았고 못그렸어도 상관없었다.
그저 그림그리는게 자다가도 깨서 그림을 그릴만큼 좋았다.
그 다음은 음악가가 되고 싶었다.
음악을 접한게 중학교 2학년. 사춘기의 질풍노도의 시기를 음악으로 채웠다.
노래도 배웠고 악기도 배웠고 화성학도 배웠다.
아마 고등학교 1학년때 어머니가 기타를 빼앗고 공부하라고 혼내지만 않았어도 내 인생은 바뀌었을 것이다.
그 다음은 다시 미술을 하기 시작했다.
미술은 나를 회귀시켰다. 마냥좋았다.
내 생각처럼 움직이지 않는 손이었어도, 빛을 잘 보지 못하는 내 눈이라 할지라도 내 마음을 표현하는데 서툴은 나였어도 연필을 들고 그림을 그리는게 좋았다.
그 다음은 사진을 찍기 시작했다.
작가가 되고 싶다는 갈망을 했다. 그런 와중에 미대에 들어갔다.
대학교에 가서 사진을 찍었다. 필름카메라를 들고 다니면서 현상하고 인화하고 현상하고 인화하고..
고3때 1년동안 한 100롤 정도 찍었던거 같다.
돈이 부족해서 아직 현상도 못한 필름이 수두룩 하다.
그리고 군대를 갔다. 그리고 같이 카메라를 놓았다. 그리고 전역했다.
그리고 졸업했다.
그리고 난
지금
프로그래머가 되었다.
UI 개발자가 되었다.
어째서 된것인지 어째서 이 길로 들어갔는지 몰랐다.
문득 생각했다.
그 모두가 초등학교 시절에 꿈꿨던 별과 별사이를 날아다니는 별자리 처럼
하나의 지도를 그려 내가 여기에 앉아있구나.
하고 미화시켜 날 치장했다.
난 내가 만든것이 상대를 만족했으면 하는 삶을 살았으면하고 꿈꿨던 것 같다.
내 몸이 불편하고 내 생각이 부족해도
내 손은로 만든것, 그린것들이 여러 사람들에게 보여지고 만족한다면 나 또한 만족했던것 같다.
내 안위도 필요 없었고 내 건강도 필요없었지.
하지만 내가 만들어갔던 모든 것. 정작 나 스스로 만족했던 것은 있었는지.
그러 것들을 사람들한테 보여주곤 나에게 만족함이 없어서 계속해서 뭔가를 만들어가는 지도 모르겠다.
내 스스로에게 만족함이 없었기에 상대에게 보여주고는 실망했는지도 모르겠지.
어쩌면 내 스스로에 대한 만족은 점점 진화해 가는 내 욕심들일지도 모르겠다.
가끔 술에 취해 내가 움직이고 일하는 원동력이 뭐라고 생각하는지 이야기 하곤한다.
그런 열등감이라는게 타인과 나를 비교해서 생기는 열등감이 아니라
나 스스로에 대해 열등함을 느끼기 때문이겠지.
열등함을 이겨내서 "내가 이긴것. 내가 이것 때문에 여태 살아온거야!" 라고 외치고 싶은것이겠지.
결국.
그래서 난 죽지 못하는 것이겠지.
나를 납득하는게 아닐까.
그 희망을 이루면 내게 내일이 있을까.

(저작권에 저촉되는 사항이 있다면 바로 삭제하겠음)
사실 우리나라는 학벌이다 뭐다 하면서 이것저것 따지는 것도 많고 말도 많다.
이번에 미네르바 일도 그렇듯 조중동에서 떠들어대는 전문대졸 무직자라는 타이틀이 왠지
"이런 병맛같은건 안봐도 병맛이므로 당연히 범인이다"라고 강조하는 듯 했다.
물론 내가 전문대졸자라서 그런느낌을 받게 된것일지도 모른다.
하지만 이건 아니지 않나 싶다.
학벌로 인해 사람이 평가 되어야만 하는건가?
왠지 이런 사회를 보고 나카타라는 영화를 보는 것만 같아 슬퍼지기까지 한다.
우리는 서울에 있는 대학을 사람을 우월하다고 생각하고
전문대졸, 고졸자들은 열등하다고 판단하는 건가 하면서 자괴감에도 빠지기도 한다.
하지만
내가 있는 곳에서 내가 하고 싶은 일을 하면서
내가 해야만하고 그 안에 노력을 심는다면 그 누가 내게 "그까짓 학력으로.."라고 말한다 할지라도
그 누구에게 당당하게 이야기 할 수 있겠지.
난 돈도 없고 시간도 없이 일만하는 일벌레다.
난 집도 없고 차도 없고 그렇다고 능력이 남보다 좋은것도 아니다.
지금은 보잘 것 없고, 깔보일지 모른다.
어쩌면 당신처럼 돈을 잘 벌지 못할지도 모르고 편하게 지내지 못할 수도 있다.
하지만 난 적어도 내가 하는 일을 위해 하얗게 불태운 적이 있었다.
그리고 적어도 내가 하는 일에 만족함을 느낀다.






13531
12
29










댓글을 달아 주세요