|
WPF 기반의 응용프로그램은 Application 개체의 생성과 동시에 시작된다고 볼 수 있으며, Application 개체의 Run() method가 반환되는 시점에 종료된다. 이렇듯 Application 개체는 응용프로그램 전반의 Life Time을 결정 짓는 핵심 역할을 담당하는 데, 상태변경이 있을 때 개발자가 자신의 코드를 포함시킬 수 있도록 몇몇 Event 를 정의하고 있다. Activated, Deactivated, DispatcherUnhandledException, Exit, SessionEnding, Startup Startup Event 일반적으로 응용프로그램의 각종 초기화를 수행하는 방법에는 Application 개체의 생성자나 Starup Event가 발생했을 때 초기화 코드를 삽입하는 방법이 있을 수 있으나, Startup Event Handler에 초기화 코드를 넣는 것이 조금 더 좋아 보인다(OnStartup() method를 overriding 하는 것도 동일하다). Startup Event 의 경우 Application type의 instance에 대한 초기화가 완전히 끝났음을 보장할 수 있기 때문이다. 실 예로 Application.Current Property 의 경우 Application type의 생성자에서는 접근할 수가 없다. 그러므로 OnStartup() method를 overriding하는 코드는 다음과 같이 구성할 수 있다. class InheritTheApp : Application 여기서 조금 특별한 부분을 발견할 수 있다. OnStartup() method내의 win 객체는 OnStartup() method 내에서 생성되었으므로, OnStartup()을 빠져나오게 되면, Dangling object가 된다. .NET Framework의 경우 이러한 Dangling object는 Garbage Collection의 대상이 되므로, 다음번에 Garbage Collector Thread가 깨어나면 정리대상이 된다.(C/C++ 개발자라면 win 객체를 InheritTheApp의 member variable로 옮기고 OnStartup() 에서 동적생성, OnShutDown() 에서 삭제하는 식의 코드를 작성하고 싶을지도 모르겠다.) 이 코드의 비밀은 Window type의 생성자에서 그 해답을 찾을 수 있다. Window Type의 생성자는 가장 마지막 단계로 Initialize() 라는 method를 호출하게 되는데 이 method의 내부 구성이 다음과 같다. private void Initialize() 이 코드를 살펴보면, Application Type의 객체가 앞서 만들어 졌다면 this.App(=Application.Current) 의 WindowsInternal collection에 자신을 추가하고, MainWindow가 없다면 자신을 MainWindow로 정한다. 이러한 이유로 OnStartup() 에서 생성된 win 객체는 현재 Application 객체의 WindowsInternal collection에 의해서 referencing되며 Dangling Object가 되지 않게 되므로, Garbage Collector의 칼날을 피할 수 있게 된다. 게다가 운이 좋으면 MainWindow가 되기도 한다.
물론 WPF를 충분히 이해하고 있는 개발자라면 이러한 WPF 개발팀의 이러한 배려가 없어도 잘 살아갈 수 있었을런지 모른다. 하지만 WPF 개발팀은 다른 선택을 하였으며, WindowsInternal Collection을 견고히 하기 위해서 이 Collection을 외부에서 변경하는 것을 허용하지 않고 있다. Application Type을 자세히 살펴본 사람이라면 이 Type이 Windows 라는 Property를 가지고 있고, 이 Property를 통해 현재 Application 객체가 관리하는(혹은 소유하는) Window 객체의 Collection을 획득할 수 있으며, 그 내용은 WindowsInternal과 같다는 것을 알고 있을 것이다. 그렇다면 Windows Property를 통해 얻은 Collection의 내용을 변경하면 무엇인가 색다른 동작을 얻을 수 있지 않을까? 게다가 다행스럽게도 Windows Property는 WindowsCollection type 이며, 이 type은 친절하게도 Add/Remove() 류의 method를 제공해 주고 있다. 하지만 이러한 operation은 동작하지 않는데, 그 이유는 Application의 Windows Property가 다음과 같이 WindowsInternal 자체가 아니라, 그의 복제본을 반환하기 때문이다. Windows Property로 획득되는 Collection은 WindowsInternal과 내용은 같을지 모르지만 전혀 다른 복사본이다. public WindowCollection Windows 앞서 Posting한 글에서 Charles Petzold의 Application = Code + Markup 의 첫번째 예제에 대한 비판적인 견해를 밝힌적이 있는데, 그 이유를 알아보자. class SayHello 사실 이 코드만으로는 완벽하게 잘 동작한다. 사실 비판적인 견해는 동작 유무를 떠난 내부적인 구조의 문제를 말하는 것이다. 다음과 같이 app.Run(); 를 호출하기 이전에 다음과 같은 코드를 넣으면 어떻게 될까? class SayHello 위 코드는 정상동작할 수 있을까? 다음으로 Application app = new Application(); 행을 가장 앞으로 옮긴다. class SayHello 이 코드는 어떻게 동작할까? 다음으로 아래 코드의 출력결과는 무엇일까? 다음으로 Window Win = new Window(); 행을 가장 앞으로 옮긴 다음 실행해보자. [STAThread] Window Type의 생성자의 동작방식을 이해하였다면, 왜 Window win = new Window(); 의 위치가 변경됨에 따라 그 결과치가 틀려지는지 충분히 이해할 수 있을 것이다. 이런 이유로 Charles Petzold 의 SayHello 예제는 다음과 같이 변경하는 것이 가장 좋다고 생각한다. class SayHello 별차이가 없어 보일 수도 있다. 그래도 눈엣가시다.
|
![]() by 김명신 카테고리
이글루 파인더
라이프로그
이글루링크
erehwon.LAB
미친병아리가 삐약삐약 소스코드위를 걷다..... 영원히 살 것처럼 꿈을 꾸.. zoops 이야기 전기쓰레빠의 매트릭스 Junghwan and Miny.. ~★~ 우하하!!~ 프로.. [ catch me if you ca.. 블로그 옮김 -> fribirdz.. 디지털을 말한다 by oojoo 더머&채니이야기 견우의 블로그 .. 이상훈의 사는 이야기 내일은 내일의 바람이 분다. 텅빈하늘 똥강아지가 멍멍~ Atelier 기억속으로 날다(Walki.. 애자일 이야기 미친감자의 프로그래밍 .. - Last Paromix - SQL Server Troubles.. Keep going with me 최근 등록된 덧글
오~, 잘 다녀오시길,..
by 쩌비 at 11/12 와.. 몸건강히 잘다녀.. by 박중석 at 11/12 유근호 : 당연히 괜찮습.. by 김명신 at 11/06 일일이 다 세어 보셨다니.. by 유근호 at 11/04 쩌비: 그쳐? 저도 그렇게.. by 김명신 at 11/03 최근 등록된 트랙백
티맥스 윈도우 스크린샷..
by The Story of A Strang.. free7942g의 생각 by free7942g's me2DAY 프로그래머 by ego+ing 사진찍는프로그래머의 생각 by eslife's me2DAY 제프리 리처의 Windows .. by 김재호의 디지털보단 아.. 이전블로그
2009년 11월
2009년 10월 2009년 09월 2009년 07월 2009년 06월 2009년 05월 2009년 04월 2009년 03월 2009년 01월 2008년 12월 2008년 11월 2008년 10월 2008년 09월 2008년 05월 2008년 04월 2008년 03월 2007년 12월 2007년 11월 2007년 10월 2007년 09월 2007년 08월 2007년 07월 2007년 06월 2007년 05월 2007년 04월 2007년 03월 2007년 01월 2006년 12월 2006년 11월 2006년 10월 2006년 09월 2006년 08월 2006년 07월 2006년 06월 2006년 05월 2006년 04월 2006년 03월 2006년 02월 2006년 01월 2005년 12월 2005년 10월 2005년 09월 2005년 07월 2005년 06월 2005년 05월 2005년 04월 2005년 03월 2005년 02월 2005년 01월 2004년 12월 2004년 11월 2004년 10월 2004년 09월 2004년 08월 2004년 07월 2004년 06월 2004년 05월 2004년 04월 2004년 02월 2004년 01월 2003년 11월 2003년 08월 |