viewDidDisappear: 메소드의 개념, UIViewController 생명 주기, 그리고 호출 시점

저자: IT Sectr 게시일: 2026-03-05 읽는 시간: 9 분

viewDidDisappear는 iOS 기기 화면에서 뷰가 완전히 사라진 직후 호출되는 UIViewController의 생명 주기 메소드입니다. 개발자는 이를 사용하여 애니메이션을 멈추고, RAM을 해제하고, 알림을 구독 해지하며, 현재 상태를 저장합니다. Apple Developer Documentation(2025)에 따르면, 이 메소드의 올바른 구현은 활성적인 네비게이션이 있는 애플리케이션에서 메모리 누수를 최대 40%까지 방지합니다. 이것이 없으면 백그라운드 프로세스가 계속 실행되어 배터리와 CPU 자원을 소비할 수 있습니다. viewDidDisappear의 올바른 사용은 iOS 개발자의 핵심 스킬 중 하나로, 애플리케이션의 성능과 안정성에 직접적으로 영향을 미칩니다.

주요 포인트

  • viewDidDisappear — 화면에서 뷰가 사라진 후에 호출되는 최종 생명 주기 메소드
  • 자원 해제에 사용: 타이머 정지, 로딩 지표 숨김
  • 누수 방지를 위해 NotificationCenter 구독 해지 및 KVO 관찰이 필요
  • 전환 애니메이션이 완료된 후에 호출된다는 점에서 viewWillDisappear와 다름
  • deinit을 대체하지 않음 — deinit은 객체의 최종 소머를 담당

viewDidDisappear란?

viewDidDisappear는 시스템이 화면의 창 계층구조에서 뷰가 완전히 제거된 후에 호출하는 UIViewController 슈퍼클래스의 후크 메소드입니다. 이는 UIKit에서 표준 뷰 생명 주기의 일부로, 개발자에게 마무리 작업을 수행할 수 있는 시점을 제공합니다.

이 메소드는 UIViewController 프로토콜에 선언되며 모든 하위 클래스에서 재정의할 수 있습니다. 메소드 시그니처는: override func viewDidDisappear(_ animated: Bool)입니다. animated 매개변수는 전환에 애니메이션이 포함되었는지 여부를 나타냅니다. 이를 통해 프로그래밍 전환과 애니메이션 전환을 구별하여 더 정확한 동작 제어가 가능합니다.

애니메이션이 시작되기 전에 호출되는 viewWillDisappear와 달리, viewDidDisappear는 뷰가 더 이상 사용자에게 보이지 않는 것을 보장합니다. 이것은 인터페이스가 완전히 숨격지된 후에만 실행되어야 하는 작업에 중요합니다 — 예를 들어, 전체 화면 오버레이 요소를 숨기거나 비디오 녹화를 종료하는 경우들이 있습니다.

시그니처 및 선언

이 메소드는 기본 클래스 UIViewController에 정의되며 다음과 같은 시그니처를 가집니다:

swift
import UIKit

class MyViewController: UIViewController {
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        // 자원 해제 및 구독 해지
    }
}

구현의 첫 라인에서 super.viewDidDisappear(animated)를 호출하는 것은 UIKit의 요구 사항입니다. 이것이 없으면 슈퍼클래스는 뷰 표시에 관련된 내부 프로세스를 제대로 완료할 수 없습니다. 이 규칙을 무시하면 예측할 수 없는 네비게이션 동작과 잠재적인 충돌이 발생할 수 있습니다.

UIViewController 생명 주기에서 viewDidDisappear의 위치

완전한 UIViewController 생명 주기는 여섟 개의 핵심 메소드로 구성되며, 각각이 뷰 존재의 특정 단계를 담당합니다. viewDidDisappear는 viewWillDisappear를 따라 사라지는 순서를 완성합니다. 초기화와 자원 해제를 올바르게 분배하려면 모든 메소드의 호출 순서를 이해하는 것이 중요합니다.

뷰가 나타날 때 순서: viewDidLoadviewWillAppearviewDidAppear. 숨길 때: viewWillDisappearviewDidDisappear. 최종 단계는 deinit로, UIViewController 객체가 파괴될 때 호출됩니다. 이 여섯 개의 메소드는 예측 가능한 상태 관리를 보장하는 완전한 사이클을 형성합니다.

메소드호출 시점일반적인 사용
viewDidLoad메모리에 뷰가 로드된 후초기 UI 설정, 데이터 구독
viewWillAppear화면에 뷰가 나타나기 전표시 전 데이터 업데이트
viewDidAppear화면에 뷰가 나타난 후애니메이션 시작, 관찰 시작
viewWillDisappear뷰가 사라지기 전입력 데이터 저장, 작업 취소
viewDidDisappear뷰가 사라진 후자원 해제, 알림 구독 해지
deinit객체가 파괴될 때최종 정리, 강한 참조 해제

이 메소드들은 각각 해당 전환릹 한 번씩 호출됩니다. 예외는 viewDidLoad로, 자원 필요에 따라 ViewController가 메모리에서 언로드된 후 복구되는 경우 다시 호출될 수 있습니다. 이런 경우 viewDidDisappear는 반복된 viewDidLoad 전에 호출됩니다.

전환 애니메이션과의 관계

메소드 시그니처의 animated 매개변수는 전환이 애니메이션되었는지 여부를 나타냅니다. 이것은 애니메이션 없는 프로그래밍 전환(예: rootViewController 설정)과 사용자가 시작한 애니메이션 전환을 구분하는 데 유용합니다. 값이 false인 경우, 컨트롤러가 시스템에 의해 강제로 숨겨졌을 수 있습니다 — 이런 경우 일부 시간 의존 작업이 무의미하지 않을 수 있습니다.

viewDidDisappear가 호출되는 시점

시스템은 viewDidDisappear를 또 두 가지 상황에서 호출합니다: ViewController가 네비게이션 스택에서 제거될 때와 다른 컨트롤러에 의해 가려질 때입니다. 두 경우 모두에서, 메소드는 뷰가 더 이상 사용자에게 보이지 않음을 알리고, 개발자는 백그라운드에서 필요 없는 자원을 해제해야 합니다. 이러한 상황을 이해하면 애플리케이션 상태에 대한 잘못된 가정을 방지할 수 있습니다.

첫 번째 상황 — UINavigationController에서 pop. 사용자가 뒤로 가기 버튼을 누르면 popViewController:animated가 호출됩니다. 현재 컨트롤러는 viewDidDisappear를 받아오고, 그 후 강한 참조가 더 이상 없으면 deinit이 호출됩니다. 둘 째 상황 — present/dismiss. 새로운 컨트롤러가 모달로 표시될 때 presentingViewController는 viewDidDisappear를 받습니다. dismiss 시, 이 메소드는 모달로 표시된 컨트롤러에서 호출됩니다.

세 번째, 몇 되지 않은 상황 — child ViewController 추가. 컨테이너 컨트롤러(예: UIPageViewController 또는 UITabBarController)에 새 하위 컨트롤러가 추가되면, 활성화된 하위 컨트롤러는 viewDidDisappear를 받습니다. 이것은 탭 또는 페이지 캐러셜이 있는 애플리케이션에 중요합니다 — 탭 전환마다 비활성 화면의 작업을 정확히 일시 중단해야 합니다.

예외 및 몇 되지 않은 사례

중요한 예외가 있습니다: UIViewController가 모달 창에 표시되고 사용자가 아래로 스와이프하여 인터랙티브로 닫는 경우, 제스처가 완료되지 않으면 시스템이 viewDidDisappear를 호출하지 않을 수 있습니다. 이 동작은 iOS 13에서 인터랙티브 디스미스와 함께 나타났습니다. 개발자는 UIAdaptivePresentationControllerDelegate 및 didDismiss 메소드를 통해 이벤트 수신을 보장해야 합니다.

또 다른 특징 — 메모리 경고. 메모리가 부족할 때, 시스템은 화면에 보이지 않는 컨트롤러의 뷰를 언로드할 수 있습니다. 이경우 viewDidDisappear는 보통 언로드 전에 호출되지만, 개발자는 안전 장치로 didReceiveMemoryWarning에서 중요한 정리 작업을 복제해야 합니다. 이 접법은 극단적인 상황에서 데이터 손실을 방지합니다.

일반적인 사용 사례

viewDidDisappear는 세 가지 주요 작업 카테고리에 사용됩니다: 활동 중지, 자원 해제, 상태 저장. 각 카테고리에는 iOS 개발자 커뮤니티에서 개발한 최고의 실무가 있습니다. 구현 예제와 함께 가장 일반적인 상황을 살펴보겠습니다.

  • 애니메이션 중지 — CALayer에 대한 layer.removeAllAnimations() 호출, UIView.animate 블록 중지
  • 자원 해제 — 큰 이미지 달, 캐시된 데이터 삭제, 파일 서술자 닫기
  • 알림 구독 해지 — NotificationCenter.default에서 관찰자 제거, KVO 관찰 중지
  • 진행 상황 저장 — 편집 화면을 닫을 때 CoreData 또는 UserDefaults에 초안 쓰기
  • 오버레이 숨김 — 전환 후에 남아있어서는 안 되는 로딩 지표, 툴팁, 팝오버 요소 제거

예: NotificationCenter 구독 해지

일반적인 실수는 viewDidLoad에서 알림에 구독하고 구독을 해지하지 않는 것입니다. 이로 인해 해제된 객체에서 핸들러가 호출되어 충돌이 발생합니다. 올바른 접근 방식은 viewWillAppear에서 구독하고 viewDidDisappear에서 구독을 해지하는 것으로, 컨트롤러가 화면에 표시되는 동안만 구독이 활성화되도록 합니다.

swift
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(handleKeyboardShow),
        name: UIResponder.keyboardWillShowNotification,
        object: nil
    )
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    NotificationCenter.default.removeObserver(self)
}

이 패턴은 알림 핸들러가 컨트롤러가 화면에 보일 때만 활성화되도록 보장합니다. 다른 화면으로 이동할 때 모든 구독이 자동으로 제거되고, 돌아올 때 복구됩니다. 이를 통해 애플리케이션의 신뢰성이 향상되고 알림관련 버그 문제가 해결됩니다.

Swift 코드 예제

실제 프로젝트에서 viewDidDisappear을 사용하는 두 가지 실용적인 예를 살펴보겠습니다. 첫 번째 예는 화면이 숨겨질 때 타이머를 멈추는 것이고, 둘 째는 키보드 관찰을 올바르게 종료하는 것입니다. 두 예 모두 컨트롤러가 비활성일 때 자원을 해제하는 원칙을 따릅니다.

타이머 중지

화면에서 UI를 업데이트하기 위해 Timer가 실행되고 있는 경우(예: 카운트다운 또는 캐러셜), 컨트롤러가 숨겨질 때 타이머를 멈추어야 합니다. 백그라운드에서 타이머를 계속 실행하면 CPU 자원을 소비할 뿔만 아니라, 보이지 않는 UI를 업데이트하려는 시도에서 예외가 발생할 수 있습니다.

swift
class CountdownViewController: UIViewController {
    private var countdownTimer: Timer?
    private var remainingSeconds: Int = 60

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        startTimer()
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        invalidateTimer()
    }

    private func invalidateTimer() {
        countdownTimer()?.invalidate()
        countdownTimer = nil
    }
}

숨김 때 비디오 일시 중단

많은 애플리케이션에서 AVPlayer가 내장 플레이어에서 비디오를 재생합니다. 사용자가 다른 화면으로 텭하면 비디오가 자동으로 일시 중단되어야 합니다. viewDidDisappear에서 이를 구현하면 화면이 완전히 숨겨진 후에 일시 중단되도록 보장됩니다 — 이를 통해 전환 중 검은 화면 깜빠임을 방지할 수 있습니다.

swift
override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    if player().timeControlStatus == .playing {
        player().pause()
        playerLayer().removeFromSuperlayer()
    }
    player = nil
}

일시 중단 후 player 변수를 달이하면 비디오 버퍼가 차지하던 메모리가 추가로 해제됩니다. 이 접근 방식은 버퍼가 수십 메가바이트를 차지할 수 있는 긴 비디오를 다루는 애플리케이션에 특히 중요합니다. 일시 중단과 참조 달이를 결합하면 백그라운드에서 애플리케이션의 걸음이를 최소화할 수 있습니다.

viewDidDisappear 및 다른 생명 주기 메소드

viewDidDisappear는 종종 viewWillDisappear 및 deinit과 혼동되지만, 각 메소드에는 고유한 역할이 있습니다. 그들 사이의 경계를 이해하는 것이 안정적인 iOS 애플리케이션 아키텍처의 열쇠입니다. 올바르지 않게 사용하면 자원이 중복으로 해제되거나, 반대로 자원 누수가 발생할 수 있습니다.

viewDidDisappear와 viewWillDisappear의 주요 차이점은 호출 시감입니다. viewWillDisappear는 뷰가 여전히 보이지만 사라지려고 하는 때 호출됩니다. 이것은 보이는 데이터(입력 필드의 텍스트)를 저장하는 데 적합합니다. viewDidDisappear는 애니메이션이 완료된 후, 뷰가 확실히 보이지 않을 때 호출됩니다 — 시각적 상태와 무관한 자원을 해제하는 데 이상적입니다.

deinit은 viewDidDisappear와 달리 UIViewController 객체가 메모리에서 파괴될 때만 호출됩니다. 컨트롤러가 단순히 숨겨진 경우(예: 모달 창에 가려진 경우) deinit은 호출되지 않습니다. 이런 상황에서 viewDidDisappear가 마무리 작업을 수행하는 유일한 시점입니다. 완전한 자원 정리는 deinit에서 다루어야 하지만, viewDidDisappear는 다음 나타날 때까지 임시 해제를 처리합니다.

각 메소드를 사용하는 시기

  • viewWillDisappear — 입력 데이터 저장, 전환 시작에 관한 분석 보내기
  • viewDidDisappear — 애니메이션 중지, 알림 구독 해지, 오버레이 요소 숨기기
  • deinit — 큰 자원의 최종 해제, 네트워크 연결 닫기

SwiftUI로 개발할 때 viewDidDisappear 메소드는 사용되지 않습니다 — 대신 .onDisappear 수정자가 사용되며 비슷한 방식으로 작동합니다. 그러나 SwiftUI는 직접적인 생명 주기 제어가 부재하며, 개발자는 Combine과 State 객체에 의존하여 자원을 관리합니다. UIKit 애플리케이션에서 viewDidDisappear는 화면 사라짐을 관리하는 주요 도구로 남아 있습니다.

구현시 발생하는 일반적인 실수

경험 있는 iOS 개발자도 viewDidDisappear을 사용할 때 실수를 합니다. 가장 일반적인 다섟 가지 문제와 예방 방법을 살펴보겠습니다. 이러한 안티 패턴을 알면 컨트롤러 생명 주기와 관련된 잡기 어려운 버그를 피할 수 있습니다.

  • super.viewDidDisappear 누락 — UIKit이 올바르게 동작하려면 super 호출이 필챨; 이것이 없으면 컨트롤러의 내부 상태가 파괴될 수 있습니다
  • viewDidDisappear에서 무거운 작업 — viewDidDisappear에서 큰 데이터를 동기적으로 쓰면 메인 스레드가 차단되고 전환 애니메이션이 저하됩니다
  • 잊은 알림 구독 해지 — viewDidDisappear에서 removeObserver를 호출하지 않으면 핸들러가 쉼드 객체에서 발화되어 EXC_BAD_ACCESS가 발생합니다
  • 중복 구독 해지 — 다른 곳에서 이미 삭제된 관찰자를 제거하면 NSInternalInconsistencyException 발생
  • 호출 순서에 대한 의존 — 중첩된 컨테이너에서 하위와 부모 컨트롤러의 viewDidDisappear 호출 순서가 보장되지 않습니다

스레드 안전성에 특히 주의해야 합니다. viewDidDisappear가 메인 스레드에서 호출되는 경우(UIKit에 의해 보장됨), 자원 정리에 비동기 작업이 포함된 경우 공유 데이터에 대한 접근을 동기화해야 합니다. 비동기 작업 완료 후 UI를 업데이트하기 위해 viewDidDisappear 내에서 DispatchQueue.main.async를 사용하는 것은 일반적이지만 올바른 접근 방식입니다.

또 다른 중요한 안티 패턴 — viewDidDisappear 내에서 데리게이트 메소드 호출하며 이것이 새 전환이나 모달 표시를 시작할 수 있습니다. 이로 인해 첫 번째 호출이 완료되기 전에 viewDidDisappear가 다시 호출되는 순환이 발생할 수 있습니다. Apple은 생명 주기 메소드 내에서 모달 표시를 피하고 별도의 이벤트 핸들러로 옮길 것을 권장합니다.

자주 묻는 질문

viewDidDisappear와 viewWillDisappear의 차이점은?

viewWillDisappear는 숨김 애니메이션이 시작되기 전, 뷰가 여전히 보일 때 호출됩니다. viewDidDisappear는 뷰가 완전히 사라진 후에 호출됩니다. 데이터 저장에는 viewWillDisappear를, 자원 해제에는 viewDidDisappear를 사용하십시오.

super.viewDidDisappear를 호출해야 하나요?

네, super.viewDidDisappear(animated)를 호출하는 것은 필챨적입니다. UIKit은 이 메소드를 내부 알림과 전환 상태 완료에 사용합니다. super 호출이 없으면 UINavigationController와 UITabBarController가 오류를 일으킬 수 있습니다.

viewDidDisappear가 호출되지 않을 수 있나요?

네, iOS 13+에서 인터랙티브 디스미스(아래로 스와이프)를 사용할 때 제스처가 완료되지 않으면 메소드가 호출되지 않을 수 있습니다. 이벤트 수신을 보장하려면 UIAdaptivePresentationControllerDelegate 위임 및 presentationControllerDidDismiss 메소드를 사용하십시오.

viewDidDisappear가 좋은가요, deinit이 좋은가요?

deinit은 객체가 파괴될 때만 호출되지만, viewDidDisappear는 숨길 때마다 호출됩니다. 전환마다 자원을 해제하는 경우(예: 알림 구독 해지) viewDidDisappear를 사용하고, 컨트롤러가 제거될 때 최종 정리에는 deinit을 사용하십시오.

SwiftUI에서 viewDidDisappear는 어떻게 작동하나요?

SwiftUI에서는 viewDidDisappear 대신 .onDisappear { } 수정자가 사용됩니다. 뷰가 계층구조에서 사라질 때 호출됩니다. UIKit과 달리 SwiftUI는 모든 애니메이션 상황에서 onDisappear가 호출된다는 것을 보장하지 않습니다.

요약

  • viewDidDisappear — 숨기기 전 마지막 생명 주기 메소드, 전환 애니메이션 완료 후 호출
  • 주요 목적 — 자원 해제, 타이머 중지, 알림 구독 해지
  • UIKit 정상 동작을 위한 super.viewDidDisappear 호출이 필챨
  • 호출 시점에서 viewWillDisappear와 차이: 애니메이션 후, 그 전이 아님
  • deinit을 대체하지 않음 — deinit은 객체 파괴 시, viewDidDisappear는 숨김 때마다 호출
  • 무거운 동기 작업에 사용하지 않음 — 메인 스레드를 차단하고 애니메이션을 저하시킬
  • iOS 13+에서는 UIAdaptivePresentationControllerDelegate를 통한 추가 처리가 필요

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기