Lifecycle
생애주기를 말한다.
프로그래밍에서는, 한 객체가 생성되고 동작이 이루어진 뒤, 프로그램 내에서 정리되는 과정까지를 말한다.
객체 지향 프로그래밍을 비롯해 여러 프로그래밍 방식에서 매우 중요한 개념이며, 최적화나 안정성을 고려하는 프로그램인 경우 중요도가 더 올라가는 개념이다.
Flutter에서 역시 각각의 Widget을 비롯해 모든 객체가 각자의 Lifecycle을 가지고 있으며, 각 객체별 Lifecycle을 컨트롤하여 앱의 동작이나 레이아웃, UI등이 잘 동작 할 수 있도록 하는 것은 매우 중요한 일이다.
Stateless Widget Lifecycle은 매우 단순하다.
아래 그림과 같다.
위젯이 만들어지고 -> 선언한 build() 함수가 빌드가 되고 -> 위젯의 필요에 의해 자연스럽게 dispose가 되는.
매우 1차원적으로 진행되기 때문에, 많이 쓰여도 리소스에 크게 영향을 미치지 않고 효율적인 프로그래밍이라고 할 수 있다.
하지만 치명적인 단점이 있는데, 위젯이 build가 된 후에는 그 안의 내용이 바뀌거나 수정이 되는것에 따라서 다시 build가 되는 것이 불가능하다는 것이다.
Stateless Widget과 비교했을 때 매우 복잡한 구조를 가진 것을 볼 수 있다.
위젯이 만들어지고 -> 쌍으로 만들어지는 State 객체가 추가적으로 생성됨 -> 추가적으로 만들어진 State 객체 안에서도 여러 LifeCycle이 존재하게 된다. -> initState를 거쳐 초기값을 만들고 -> build로 넘어감 -> build 함수에 있을 때 보통 UI가 표시되고 동작하는 것을 볼 수 있다. -> 이 상태에서 setState(), didUpdatedWidget() 함수를 통해 다시 빌드가 되기도 함 -> build가 된 위젯이 더이상 activate 하지 않은 시점이 되면 dispose 함수를 통해 필요에 의해 리소스로 가지고 있던 객체들을 dispose 시키거나, super 객체를 통해서 상위 객체들이 알아서 dispose 상태가 되고 최종적으로 위젯이 dispose가 된다.
위와 같이 매우 복잡한 구조를 가지고 되는데, 중점적으로 볼 부문은, initState 과정과 build가 되는 과정이 적절하게 분리가 되어 있는 점이다.
build() 함수 내에서 변수가 선언이 되거나, 할당이 되는 경우에는 setState()나 didUpdatedWidget()이 다시 재호출되더라도 build 안에서 다시 리셋이 되기 때문에, 웬만해서는 initState 과정에서 해결하거나, State 객체에 밖으로 변수를 빼내서 setState 사이클 안에서 벗어난 변수를 활용하는 것이 매우 중요.
Dispose 부분도 매우 중요하다.
예를 들어, 채팅 서비스를 한다고 했을 때, 채팅에 대한 연결을 풀어주지 않으면, 상시로 들어오는 데이터가 계속 쌓이게 되어, 위젯 뿐 아니라 앱에 대한 최적화나 성능이 현저히 떨어지게 될 수 있다.
위에서 간단하게 설명했듯, 각 Widget 내부 뿐 아니라, 다른 Widget 간의 상호작용, 전역 변수와 함수에 대한 관리, 시기 적절한 dispose/initState 활용, 등등 이러한 문제점들을 해결하기 위해 Flutter에는 여러 상태관리 모델이 오픈소스로 개발되어 공유되고 있다. 대표적으로는, Riverpod, BLoC, GetX, Provider, Redux 등등. 이에 대한 부분은 다른 글에서 다뤄보겠다!