![[ Swift ] iOS 앱 라이프사이클](https://image.inblog.dev?url=https%3A%2F%2Finblog.ai%2Fapi%2Fog-custom%3Ftitle%3D%25EB%25A7%25A4%25EC%259D%25BC%2B%25EC%259E%2591%25EC%258B%25AC%25EC%2582%25BC%25EC%259D%25BC%2B%25EC%258A%25A4%25EC%259C%2584%25ED%2594%2584%25ED%258A%25B8%26tag%3DTemplate%2B1%26description%3DiOS%2B%25EC%2595%25B1%2B%25EB%259D%25BC%25EC%259D%25B4%25ED%2594%2584%25EC%2582%25AC%25EC%259D%25B4%25ED%2581%25B4%26template%3D3%26backgroundImage%3Dhttps%253A%252F%252Fsource.inblog.dev%252Fog_image%252Fdefault.png%26bgStartColor%3D%2523ffffff%26bgEndColor%3D%2523ffffff%26textColor%3D%2523000000%26tagColor%3D%2523000000%26descriptionColor%3D%2523000000%26logoUrl%3Dhttps%253A%252F%252Fsource.inblog.dev%252Flogo%252F2025-12-08T03%253A43%253A12.522Z-5af2a801-26a1-4f2b-b703-71b3ca15126b%26blogTitle%3DRN%2B%25EC%2582%25BD%25EC%25A7%2588%2B%25EC%259D%25BC%25EC%25A7%2580&w=3840&q=75)
iOS는 앱을 “항상 켜져 있는 프로그램”처럼 두지 않고, 배터리/성능/메모리를 아끼기 위해 앱의 실행을 상태(state)로 관리한다.
상황에 따라 깨우고, 잠재우고, 필요하면 종료하는 규칙, 이걸 라이프사이클이라 한다.
3가지 레벨
먼저 헷갈리기 쉬운 포인트부터 정리한다. 프로세스 / 앱 / 창(UIWindow) 자체는 iOS 13 이전에도 존재한다. 다만 iOS 13부터 ‘Scene(씬)’ 개념이 도입되면서, 창(윈도우)을 OS가 공식적으로 관리하는 단위가 생겼고 UI 라이프사이클이 더 명확히 분리되었다.
A. 프로세스(Process) 레벨
앱이 실행되면 하나의 프로세스가 뜬다.
프로세스가 종료되면 앱은 완전히 종료된 것이고, 다시 실행하면 처음부터 시작한다.
B. 앱(App) 레벨
앱 전체에서 공통으로 발생하는 사건들을 다루는 레벨이다.
예: 앱 실행 시작, 종료 직전, 메모리 경고 등
C. 씬(Scene) 레벨 = “창(윈도우) 하나” (iOS 13+에서 공식화)
iOS 13 이전에도 화면을 띄우는 UIWindow(창)는 있었지만, 보통 “앱의 메인 화면” 중심으로 관리되는 흐름이었다.
iOS 13부터는 Scene이 ‘UI 인스턴스(창) 하나’를 대표하는 공식 단위가 되면서,
창마다 활성/비활성/백그라운드 같은 상태 전환이 생길 수 있고
한 앱 안에 여러 Scene(= 여러 창/여러 UI 인스턴스)이 존재할 수도 있게 된다.
대표 상태
✅ Active(활성)
사용자가 앱의 어떤 창을 실제로 보고 있고 입력(터치/키보드)을 받는 상태다.
“지금 사용 중”인 상태다.
✅ Inactive(비활성, 잠깐 멈춤)
화면은 앞에 있지만 잠깐 입력을 못 받는 상태다.
예: 전화/알림/앱 전환 제스처로 잠깐 멈칫할 때
보통 Active ↔ Background 사이에 잠깐 낀다.
✅ Background(백그라운드)
앱이 화면 밖으로 나간 상태다(홈 화면으로 가거나 다른 앱으로 전환).
이때부터 OS가 제한을 걸기 시작한다.
“정리하고 저장할 거 있으면 해라”에 가까운 구간이다.
✅ Suspended(정지/중단)
백그라운드에 있는 앱(또는 특정 창/씬)을 OS가 완전히 ‘잠재운’ 상태다.
메모리는 남아 있을 수 있지만 코드는 실행되지 않는다.
여기서 뭘 하려고 기대하면 안 되고, Background로 들어갈 때 이미 저장/정리를 해두는 게 안전하다.
Background/정지 ≠ 종료
Background: 죽은 게 아니다. 뒤에 있을 뿐이다.
Suspended: “멈춤”이지 “종료”가 아니다. (실행만 멈춘다)
Terminate(종료): 진짜로 프로세스가 내려간다.
그리고 iOS는 상황에 따라 앱을 종료할 수 있다.
메모리 부족 등으로 OS가 정리
사용자가 앱 스위처에서 강제 종료
크래시
그래서 안전한 사고방식은 다음과 같다.
언제든 종료될 수 있으니, 중요한 것은 백그라운드로 갈 때 저장하는 것이다.
(iOS 13+) 멀티윈도우/멀티씬에서 달라지는 점
iOS 13부터 Scene 시스템이 들어오면서, 한 앱이 여러 개의 창(씬)을 가질 수 있게 된다. 이때부터 “앱 상태”만 보고 판단하면 실수하기 쉬워진다.
(1) 창(씬)마다 상태가 다를 수 있다
예를 들어 다음과 같은 상황이 가능하다.
Scene A(창 A): 사용자가 보고 있음 → Active
Scene B(창 B): 다른 창/다른 공간에 있음 → Background
즉, 다음처럼 생각해야 한다.
“앱이 백그라운드다”라고 단정하기보다 “어느 창(씬)이 백그라운드냐”를 봐야 한다.
(2) 상태 저장은 “창(씬) 단위”로 하는 게 자연스럽다
멀티윈도우/멀티씬 환경에서 사용자는 이런 경험을 기대한다.
창 A는 A대로 보던 화면/문서 유지
창 B는 B대로 다른 화면/문서 유지
그래서 설계를 할 때는 다음이 중요하다.
“현재 열어둔 문서”, “스크롤 위치”, “선택된 탭” 같은 화면 상태는
창(씬)마다 따로 저장/복원하는 것이 맞다.
상태별 할일?
Active로 돌아올 때
화면 최신화(필요하면 데이터 새로고침)
일시정지했던 작업(애니메이션/타이머/센서 등) 재개
Inactive로 갈 때(잠깐 멈춤)
민감한 입력/결제 같은 흐름이면 잠깐 멈추거나 UI를 보호
Background로 갈 때(가장 중요)
저장: 작성 중인 데이터, 임시 상태
정리: 타이머/리소스/네트워크 작업 정돈
“곧 suspended 될 수 있다”라고 생각하고 빠르게 마무리
Suspended
코드 실행이 없다.
⚠️그러니 이 단계에서 뭘 하겠다는 설계는 위험하다.