validateNow(), callLater() 그리고 라이프사이클
Flex/Air  2009.07.11 01:15  
라이프사이클은 아키텍쳐 입니다. 
아키텍쳐는 흐름이며 구성 입니다.
흐름과 구성을 아는 것이야 말로 전문가로 가는 지름길이라고 할 수 있습니다.

Flex의 라이프사이클을 이해하는데 있어서 가장 중요한 부분을 시작으로 이야기를 풀어보겠습니다.

Flex의 모든 비주얼 컴포넌트들은 UIComponent를 최상위 조상으로 하고 있습니다. 
Button도 UIComponent이고, DataGrid도 UIComponent 입니다.
UIComponent가 화면에 보여질 때의 과정을 살펴보면, 

첫 번째로 컴포넌트의 속성들을 설정하고(commitProperties() 메소드 호출)
두 번째로 컴포넌트의 기본 크기를 설정하고(measure() 메소드 호출)
마지막으로 속성과 기본 크기를 바탕으로 화면에 표시 합니다.(updateDisplayList() 메소드 호출)


위에서 언급된 3가지 메소드는 컴포넌트가 화면에 보여질 때 플레시플레이어에 의해 자동으로 호출 됩니다.
이 메소드들은 개발자가 재정의 할 수 있으며, 커스텀 컴포넌트를 만드는데 있어서 반드시 알아야할 사항 입니다.
이렇게 각 역할별로 분리된 메소드는 개발자 입장에서 유지보수를 향상시키고 플래시플레이어 입장에서 성능을 최적화할 수 있습니다.

지금까지 가장 기초적인 라이프사이클에 대해 이야기 했습니다. 이러한 기본지식을 알고 있는 상태에서 계속 이야기를 진행 하겠습니다.

Label 컨트롤의 text 속성을 변경하면 어떤 일이 벌어질까요?
일단 결과 자체만 예측해 보면 화면에 보여지는 Lable의 text는 바뀔 것이고 text 길이에 따라 Label의 크기도 변경될 것입니다. 하지만 Label 클래스의 구현된 text 속성에는 방금 예측했던 코드들이 들어가 있지 않습니다.

public function set text(value:String):void
 {
     textSet = true;

     if (!value)
         value = "";

     if (!isHTML && value == _text)
         return;
     
     _text = value;
     textChanged = true;

     _htmlText = null;
     
     explicitHTMLText = null;

     invalidateProperties();
     invalidateSize();
     invalidateDisplayList();

     dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
 }

위 코드에서 알 수 있듯이 예측했던 결과에 대한 코드(속성이 변경됨에 따라 영향을 받는 다른 속성들의 변경이나 크기를 바꾸거나 화면에 보여지기 위한 코드들)는 전혀 없습니다. 단지 _text 변수에 새로운 값을 세팅하는 것 이외에 특별함을 찾아볼 수 없습니다. 하지만 여기서 주의깊게 봐야할 3가지 메소드가 있습니다.

 invalidateProperties();
  - commitProperties() 메소드 호출을 예약 합니다.

invalidateSize();
  - measure() 메소드 호출을 예약 합니다.

invalidateDisplayList();
  - updateDisplayList() 메소드 호출을 예약 합니다.


invalidate~() 메소드들이 하는 역할은 3가지의 라이프사이클 메소드 호출을 예약하는 것 입니다.
그렇다면 Label 클래스의 text 속성에 구현된 코드는 단지 예약만 하고 끝난다는 뜻인데... 과연 예약된 라이프사이클 메소드는 언제 호출되는 것일까요? 또 왜 바로 라이프사이클 메소드를 호출하지 않고 예약하는 것일까요?


 궁금증1. 예약된 라이프사이클 메소드는 언제 호출 되는가?
개발자가 정의한 코드 또는 Flex Framework에 정의된 코드(예를들면, Label 클래스의 text 속성에 구현된 코드)가 모두 종료되면, 플래시플레이어에 의해 예약된 라이프사이클 메소드가 호출 됩니다.

궁금증2. 왜 바로 호출하지 않고 예약하는 것인가?
답부터 말하자면 성능 때문 입니다. 만약 예약하지 않고 바로 호출한다고 가정하고, Label 클래스의 text 속성을 여러번 설정하게 되면 매 설정마다 화면에 보여주기 위한 엄청난 코드가 실행됩니다. 하지만 화면에 보여지는 결과는 마지막 설정 값이 되겠죠. 플래시플레이어 입장에서는 한번에 text 속성이 설정되는 횟수에 관계없이 마지막 설정에 따른 결과만 보여주면 되기 때문에 나머지 설정들은 무의미 합니다. 따라서 text 속성에서는 단지 예약만 하는 것 입니다. 그렇다면 이런 의문을 제기할 수 있습니다. 예약을 3번 한다치면 라이프사이클 메소드도 3번 호출되어 결국 시점의 차이일뿐 실행되는 코드양은 똑같지 않냐? 라고 말이죠. 하지만 예약은 중첩되지 않습니다.

이것이 Flex 라이프사이클의 핵심이자 아키텍쳐 입니다. 이런 흐름과 구조를 알고 있어야 다음에 나올 두 가지 메소드를 이해할 수 있습니다.

validateNow()
이 메소드가 호출되면 예약된 라이프사이클 메소드가 즉시 수행 됩니다. 이 것은 개발자가 직접 라이프사이클을 제어할 수 있다는 뜻 입니다. 모든 코드가 종료 되더라도, 이 메소드에 의해 실행된 라이프사이클 메소드는 다시 실행되지 않습니다. 

이 메소드의 용도는 하나의 주기 안에서 어떤 컴포넌트의 속성을 변경하고, 그 변경에 따른 결과에 접근하고자 할 때 입니다. 변경에 따른 결과는 라이프사이클 메소드가 수행된 후에 가능하기 대문에, 이 메소드를 호출함으로써 하나의 주기 안에서 라이프사이클 메소드 호출을 포함 시키는 것 입니다.

callLater(method:Function, args:Array)
인자로 전달되는 메소드의 호출을 예약 합니다. 예약된 메소드가 호출되는 시점은 다음과 같습니다.

1. 프로그램 상의 코드 실행
2. 예약된 라이프사이클 메소드 실행
3. callLater()로 예약된 메소드 실행

이 메소드의 용도는 validateNow()와 동일합니다. 하지만 작동방식은 완전히 반대 됩니다. validateNow()는 라이프사이클 메소드를 강제로 하나의 주기안에 포함시켜 호출하는 반면, 이 메소드는 라이프사이클 메소드가 수행될 때 까지 기다린 후 예약된 메소드가 호출 됩니다.


끝으로...
validateNow() 와 callLater()의 작동 방식은 정 반대지만, 결과 자체는 동일 합니다. 컴포넌트를 제작하거나 이미 만들어진 컴포넌트를 이용함에 있어서, 이 두 메소드중 어떤 것을 사용해야 할지는 프로그램의 아키텍쳐를 잘 알고 있는 개발자의 몫 입니다.

출처: http://jjaeko.tistory.com/109