[GetX] 컨트롤러가 제때 안 죽을 때

broccolism·2021년 9월 2일
3

dev-story

목록 보기
2/2

3줄 요약
1. 컨트롤러는 페이지가 닫혀도 죽지 않음
2. Get.toNamed()를 사용하면 스크린이 나온 뒤에 할 일을 추가로 적을 수 있음
3. 데이터 초기화 함수를 잘 활용하면 컨트롤러 1개로 여러 스크린 커버 가능

🚨 컨트롤러가.. 왜 안 죽지?

유저의 프로필 정보를 받아오는 UserProfileController 가 있었다. 어느 화면에서든 유저의 프로필 사진이나 닉네임을 누르면, 그 사람 프로필로 이동하면서 이 컨트롤러를 계속 사용하게 되었다.

  • naive implementation
    에.. 컨트롤러가 초기화 될 때 유저 정보를 받아오면 되니까 onInit() 함수에서 데이터를 받아오면 되겠지?
// UserProfileController
 onInit() async {
  await getData();
  super.onInit();
}
  • 문제점

    유저 A의 프로필을 봄 -> 뒤로가기 -> 유저 B의 프로필을 보고싶음

컨트롤러는 화면이 닫힐 때 같이 close 되지 않는다. 컨트롤러의 생명주기와 위젯의 생명 주기는 완전 별개의 것이다. 생각해보면 컨트롤러 입장에서 화면이 닫혔는지 아닌지 알 방법이 없다!
따라서 유저 A의 프로필을 본 뒤, 유저 B의 프로필을 보러 들어갔을 때에는 기존 컨트롤러가 계속 살아있는 상태이고 컨트롤러가 초기화 될 때 불리는 onInit() 함수는 절대 불리지 않는다. 결국 유저 B의 프로필 사진을 눌러서 들어간 스크린에 유저 A의 데이터가 보여지게 된다.

🧐 그럼.. 화면이 닫힐 때마다 컨트롤러를 억지로 죽여야 하나?

  • 그렇게 되면 매번 컨트롤러를 새로 메모리에 올리고, 변수를 초기화 해주는 등 너무 많은 cost가 든다.
  • 또한 getX에서 이를 지원하는 함수가 특별히 없어보인다. getX의 철학을 무시하는 일이기 때문이다.

✅ 그러면 컨트롤러 안에 있던 애들만 죽이자

UserProfileController에 함수 하나를 만든다.

// UserProfileController

void removeData() {
  _userProfile.value = null;
}

그리고 다른 사람의 프로필로 이동할 때마다 기존 데이터를 지우고 스크린을 띄워준다.

// view

UserProfileController.to.removeData();
Get.toNamed( ... );
await UserProfileController.to.getUserProfile();
UserProfileController.to.getReviews();

특이한건, Get.toNamed() 이후의 코드도 실행이 잘 된다는 점이다. 그러니까 이 코드대로라면 데이터 삭제 -> 새 스크린으로 이동 -> 데이터 불러오기의 순서대로 작동하기 때문에, 처음에는 아주 잠깐 하얀 화면이 보였다가 유저 프로필이 제대로 보이게 된다.

✅✅ 기존에 있던 데이터를 꼭 지워야 하는 상황에만 죽이자

만약 이런 시나리오라면 굳이 컨트롤러의 데이터를 지우고 정보를 다시 받아올 필요가 없다.

유저 A의 프로필을 봄 -> 뒤로가기 -> 유저 A의 프로필을 다시 보고싶음

어차피 동일한 데이터를 보여줘야 하기 때문이다. 그래서 컨트롤러 안에 기존에 열람한 유저 프로필의 아이디와 새롭게 보려는 유저 프로필의 아이디가 같은지 확인하는 함수를 만들었다. 만약 같다면 아무 일도 일어나지 않고, 다르다면 데이터 삭제 -> 새 스크린으로 이동 -> 데이터 불러오기 의 과정을 거치게 된다.

profile
자라는 브로콜리 | 글에 대한 의견 환영합니다: mile3880@gmail.com

0개의 댓글