화면으로 돌아올 때 `viewDidLoad`의 갱신 코드가 다시 실행되지 않습니다. `viewDidLoad`, `viewWillAppear`, `viewDidAppear`를 어떻게 나눠야 하나요?
잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?
답변과 점검 포인트 펼치기답변 접기
구두 답변
정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.
viewDidLoad에 모든 갱신을 넣는 것이 문제의 원인입니다. 뷰가 메모리에 처음 로드된 뒤 한 번 준비하면 되는 연결·정적 구성은 viewDidLoad에 두고, 화면에 다시 들어올 때 최신 상태를 표현해야 하는 작업은 viewWillAppear에 둡니다. 실제 전환이 끝난 뒤 화면에 보여야 한다는 전제가 있는 안내·애니메이션·가시성 측정은 viewDidAppear에 배치하겠습니다. 이 구분은 메서드 호출 횟수를 암기하는 문제가 아니라, 상태의 소유자와 반복 실행해도 안전한지 정하는 문제입니다.
처음 로드할 것과 매번 갱신할 것을 나눕니다
viewDidLoad는 뷰 계층이 처음 만들어지고 아웃렛이 연결된 뒤 호출됩니다. 버튼 타깃 설정, 정적 제약 조건, 데이터 소스·delegate 지정, 한 번만 필요한 서브뷰 생성처럼 같은 뷰 인스턴스에 한 번 초기화할 항목을 둡니다. 그러나 뷰 컨트롤러가 화면에서 내려갔다고 뷰가 반드시 해제되는 것은 아닙니다. 다른 화면에서 프로필이나 주문 상태가 바뀐 뒤 돌아오면 기존 뷰가 그대로 남아 viewDidLoad의 네트워크 조회는 다시 실행되지 않습니다. 뷰가 해제되어 새로 로드되면 viewDidLoad도 다시 호출될 수 있으므로 절대적인 앱 전체 1회라는 뜻도 아닙니다.
viewWillAppear는 전환 애니메이션이 끝나기 전에 화면이 곧 나타난다는 지점입니다. 저장소에서 최신 상태를 읽어 레이블·목록·내비게이션 바를 갱신하거나, 화면이 보이는 동안만 필요한 관찰을 시작하기에 적합합니다. 다만 이 메서드는 재진입 때마다 호출될 수 있으므로 서브뷰를 계속 추가하거나 배열에 append하지 않고, 기존 모델을 교체하거나 식별자로 중복을 제거하는 방식으로 멱등성을 확보하겠습니다. 관찰자·타이머·작업을 시작한다면 이미 시작했는지 추적하고, 화면이 사라질 때 해제하거나 화면 소유자와 동일한 수명의 토큰을 사용합니다.
화면에 보인 뒤의 작업은 늦춥니다
viewDidAppear는 appearance 전환이 완료된 뒤 호출되므로 첫 화면 튜토리얼, 실제 표시를 기준으로 시작할 애니메이션, 사용자에게 보이는 동안만 측정할 지표를 둡니다. 표시 전에 시작하면 사용자에게 보이지 않는 시간까지 체류 시간으로 계산하거나, 전환 애니메이션과 경쟁할 수 있습니다. 반대로 데이터 조회 자체를 항상 viewDidAppear에 넣으면 화면 표시를 늦추고 재등장 때 불필요한 작업이 반복될 수 있으므로, 최신 데이터가 필요하면 viewWillAppear에서 시작하되 UI 반영은 현재 화면 상태를 확인하겠습니다.
비동기 결과에는 화면 생명주기와 요청 세대를 함께 적용합니다. 화면이 사라졌으면 취소하거나 결과를 버리고, 같은 화면에서 새로 시작한 요청이 있다면 이전 요청의 늦은 응답이 최신 값을 덮지 못하게 세대 번호를 비교합니다. 이 검사는 오래된 응답이 새 화면 상태를 덮는 경쟁을 막습니다. 요청별 세대 번호는 어떤 응답이 최신 요청에 속하는지 판별하는 도구이며, 취소 자체가 늦은 완료를 없애 준다고 가정하지 않습니다. 작업을 캐시해 다음 등장 때 즉시 표시할지, 매번 취소하고 새로 읽을지는 최신성·비용·작업의 부수 효과를 기준으로 선택합니다.
검증은 push·modal·navigation·tab 전환에서 로그를 남겨 콜백 순서를 확인하고, 뷰는 유지한 채 다시 나타나는 경우와 메모리 압박 뒤 새로 로드되는 경우를 나눕니다. 반복 등장으로 서브뷰·옵저버·타이머가 중복되지 않는지, 화면이 사라진 뒤 늦은 네트워크 응답이 적용되지 않는지, 컨테이너가 appearance 전파를 바꾼 경우 자식 계약이 어떻게 달라지는지 확인하겠습니다.
득점 포인트
이해가 드러나는 지점을 확인해 보세요.
- viewDidLoad의 초기 구성, viewWillAppear의 재등장 갱신, viewDidAppear의 실제 표시 후 작업을 목적에 맞춰 나눈다.
- 반복 호출에서 중복 서브뷰·옵저버·타이머를 막는 멱등성·정리 시점을 설명한다.
- 비동기 결과에 화면 수명과 요청 세대를 적용해 사라진 화면이나 오래된 요청의 갱신을 차단한다.
감점 포인트
놓치기 쉬운 조건과 오해를 짚어 보세요.
- viewDidLoad가 앱 실행 동안 정확히 한 번뿐이라고 단정한다.
- viewWillAppear마다 서브뷰·관찰자·데이터를 누적해 재등장할수록 중복을 만든다.
- 응답이 도착했다는 이유만으로 화면의 현재 수명과 최신 요청 여부를 확인하지 않는다.
더 파고들 거리
하나 더 질문하며 이해의 범위를 넓혀 보세요.
- navigation·modal·tab을 오갈 때 viewDidLoad와 appearance callback은 어떤 조건에서 다시 호출되나요?
- 화면이 사라졌습니다. 진행 중 다운로드·검색·캐시 작업 중 무엇을 취소하고 무엇을 유지하나요?
- 컨테이너가 appearance 전파를 끈 경우 자식 화면의 갱신 책임을 어디에 둘지 정해 보세요.
득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.
원리부터 공부하고 싶다면
답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.