Deep_Dev
article thumbnail

생λͺ…μ£ΌκΈ° ( LifeCycle )

생λͺ…μ£ΌκΈ°λΌλŠ” 것은 μ•±μ˜ 졜초 μ‹€ν–‰λΆ€ν„° 앱이 μ™„μ „νžˆ μ’…λ£Œλ˜κΈ°κΉŒμ§€ 앱이 κ°€μ§€λŠ” μƒνƒœμ™€ κ·Έ μƒνƒœλ“€ μ‚¬μ΄μ˜ 전이λ₯Ό λ§ν•œλ‹€.

μ•±μ˜ μƒνƒœλŠ” 앱이 ν˜„μž¬ μ–΄λ– ν•œ 것을 ν•  수 μžˆλŠ”κ°€λ₯Ό κ²°μ •ν•œλ‹€.

 

μ•±μ˜ 생λͺ…μ£ΌκΈ° ( App's Life Cycle )

App의 생λͺ…μ£ΌκΈ°λŠ” APP의 μ‹€ν–‰/μ’…λ£Œ 및 App이 Foreground/Background μƒνƒœμ— μžˆμ„ λ•Œ, μ‹œμŠ€ν…œμ΄ λ°œμƒμ‹œν‚€λŠ” event에 μ˜ν•΄ App의 μƒνƒœκ°€ μ „ν™˜λ˜λŠ” 과정을 λ§ν•œλ‹€.

 

μΉ΄μΉ΄μ˜€ν†‘ μ•±μœΌλ‘œ 카톑을 ν•˜κ³  μžˆλŠ” 도쀑에 μ „ν™”κ°€ 왔을 λ•Œ 앱이 ν™”λ©΄μƒμ—μ„œ 보여지지 μ•ŠλŠ” μƒνƒœμΈ Background μƒνƒœμ™€

앱이 화면에 μ˜¬λΌμ™€μžˆλŠ” μƒνƒœμΈ Foreground λ“±κ³Ό 같은 μƒνƒœλ“€μ„ μ •μ˜ν•œ 것이닀.

 


iOSμ—μ„œ 앱을 μ‹€ν–‰ν•˜λ©΄ 무슨 일이 λ²Œμ–΄μ§ˆκΉŒ ?

 

iOS앱은 Objective - C 기반으둜 μž‘λ™ν•˜κΈ° λ•Œλ¬Έμ— 앱은 main ν•¨μˆ˜μ—μ„œ μ‹œμž‘ν•œλ‹€. λ‹€λ§Œ, iOS의 핡심 라이브러리인 UIKit Frameworkκ°€ main ν•¨μˆ˜λ₯Ό κ΄€λ¦¬ν•˜κΈ° λ•Œλ¬Έμ— μ•± κ°œλ°œμžλ“€μ΄ 직접 main ν•¨μˆ˜μ— μ½”λ“œλ₯Ό μž‘μ„±ν•˜μ§€λŠ” μ•ŠλŠ”λ‹€. 

UIKit은 main ν•¨μˆ˜λ₯Ό λ‹€λ£¨λŠ” κ³Όμ •μ—μ„œ UIApplicationMain ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•œλ‹€. 이 ν•¨μˆ˜λ₯Ό 톡해 UIApplication 객체가 μƒμ„±λ˜λŠ”λ°, 이 객체λ₯Ό 톡해 μ•± κ°œλ°œμžλŠ” μ•±μ˜ 싀행에 λΆ€λΆ„μ μœΌλ‘œ κ΄€μ—¬ν•  수 μžˆλ‹€. 

 

앱이 μ‹€ν–‰λ˜λ©΄ λ°œμƒλ˜λŠ” 이벀트 정리

 

1. UIApplication 객체가 생성됨

2. @UIApplicationMain λ˜λŠ” @Main μ–΄λ…Έν…Œμ΄μ…˜μ΄ μžˆλŠ” 클래슀λ₯Ό μ°Ύμ•„ AppDelegate 객체 생성

3. Main Event Loopλ₯Ό μ‹€ν–‰ ( touch, text input λ“± μ‚¬μš©μžμ˜ μ•‘μ…˜μ„ λ°›λŠ” 루프 )

 

 


Main Run Loop

그림으둜 ν™•μΈν•΄λ³΄μž

Main Run LoopλΌλŠ” 것은 μœ μ €κ°€ μΌμœΌν‚€λŠ” μ΄λ²€νŠΈλ“€μ„ μ²˜λ¦¬ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€μ΄λ‹€. UIApplicationκ°μ²΄λŠ” 앱이 싀행될 λ•Œ, Main Run Loopλ₯Ό μ‹€ν–‰ν•˜κ³  이 Main Run Loopλ₯Ό View와 κ΄€λ ¨λœ μ΄λ²€νŠΈλ‚˜ View의 μ—…λ°μ΄νŠΈμ— ν™œμš©ν•œλ‹€. λ˜ν•œ, Main Run LoopλŠ” View와 κ΄€λ ¨λ˜μ–΄ 있기 λ•Œλ¬Έμ— Main μ“°λ ˆλ“œμ—μ„œ μ‹€ν–‰λœλ‹€.

μœ μ €κ°€ μΌμœΌν‚€λŠ” 이벀트의 처리 과정을 μˆœμ„œλ‘œ μ •λ¦¬ν•˜μžλ©΄,

 

1. μœ μ €κ°€ 이벀트λ₯Ό λ°œμƒμ‹œν‚¨λ‹€. ( λ²„νŠΌ ν„°μΉ˜, ν™”λ©΄ μŠ€μ™€μ΄ν”„ λ“± )

2. μ‹œμŠ€ν…œμ„ 톡해 μ΄λ²€νŠΈκ°€ μƒμ„±λœλ‹€. 

3. UIKit ν”„λ ˆμž„μ›Œν¬λ₯Ό 톡해 μƒμ„±λœ port둜 ν•΄λ‹Ή μ΄λ²€νŠΈκ°€ μ•±μœΌλ‘œ μ „λ‹¬λœλ‹€. 

4. μ΄λ²€νŠΈλŠ” μ•± λ‚΄λΆ€μ μœΌλ‘œ Queue의 ν˜•νƒœλ‘œ μ •λ¦¬λ˜κ³  Event Queue에 μŒ“μΈλ‹€.

5. Event Queue에 μžˆλŠ” μ΄λ²€νŠΈλ“€μ΄ Main Run Loop에 ν•˜λ‚˜μ”© λ§€ν•‘λœλ‹€.

6. UIApplication κ°μ²΄λŠ” 이 λ•Œ κ°€μž₯ λ¨Όμ € 이벀트λ₯Ό 객체둜 μ–΄λ–€ 것이 μ‹€ν–‰λ˜μ–΄μ•Ό ν•˜λŠ”μ§€ κ²°μ •ν•œλ‹€. 

 

 


μ•žμ˜ λ‚΄μš©κΉŒμ§€ μ‚¬μš©μžκ°€ 앱에 이벀트λ₯Ό μ „λ‹¬ν•œ ν›„ 

μ•±μ˜ μ‹€ν–‰κΉŒμ§€ μ–΄λ–€ 과정을 톡해 μ΄λ€„μ§€λŠ”μ§€ μ•Œμ•„λ³΄μ•˜λ‹€.

 

μ—¬κΈ°μ„œλΆ€ν„°λŠ” iOSμ•±μ˜ μ‹€ν–‰μ „ μƒνƒœ, μ‹€ν–‰ ν›„ μƒνƒœ 등을 μžμ„Ένžˆ μ•Œμ•„λ³΄κ² λ‹€.

 

 

μ•± μƒνƒœ ( App State )

μ•±μ˜ μƒνƒœλŠ” 총 3κ°€μ§€λ‘œ κ΅¬λΆ„λœλ‹€.

 

1. Not Running

앱이 μ‹€ν–‰λ˜μ§€ μ•Šμ•˜κ±°λ‚˜, μ™„μ „νžˆ μ’…λ£Œλ˜μ–΄ μž‘λ™ν•˜μ§€ μ•ŠλŠ” μƒνƒœ

 

2. Inactive ( Foreground )

앱이 μ‹€ν–‰λ˜λ©΄μ„œ Foreground에 μ§„μž…ν•˜μ§€λ§Œ, μ–΄λ–€ μ΄λ²€νŠΈλ„ λ°œμƒλ˜μ§€ μ•Šμ€ μƒνƒœμ΄λ‹€.

μ•±μ˜ μƒνƒœ μ „ν™˜κ³Όμ •μ—μ„œ 잠깐 λ¨Έλ¬΄λŠ” 단계

 

3. active ( Foreground )

앱이 싀행쀑이며, Foreground에 있고, 이벀트λ₯Ό λ°›κ³  μžˆλŠ” μƒνƒœμ΄λ‹€.

 

4. Background 

앱이 λ°±κ·ΈλΌμš΄λ“œμ— 있으며, λ‹€λ₯Έ μ•±μœΌλ‘œ μ „ν™˜λ˜μ—ˆκ±°λ‚˜ ν™ˆλ²„νŠΌμ„ 눌러 λ°–μœΌλ‘œ λ‚˜κ°”μ„ λ•Œμ˜ μƒνƒœμ΄λ‹€.

예λ₯Ό λ“€μ–΄, 멜둠 App을 μΌœλ†“κ³  λ‹€λ₯Έ App을 μ‚¬μš©ν•΄λ„ μž¬μƒν•œ μŒμ•…μ΄ 계속 μ‹€ν–‰λ˜λŠ” κ²½μš°μ΄λ‹€.

일정 μ‹œκ°„μ΄ μ§€λ‚˜ 앱은 Suspened μƒνƒœλ‘œ λ°”λ€Œκ²Œ λœλ‹€.

 

5. Suspened

앱이 λ°±κ·ΈλΌμš΄λ“œ μƒνƒœμ— μžˆμ§€λ§Œ, 아무 μ½”λ“œλ„ μ‹€ν–‰ν•˜μ§€ μ•Šμ€ μƒνƒœμ΄λ‹€. 

λ°±κ·ΈλΌμš΄λ“œμ—μ„œ νŠΉλ³„ν•œ μž‘μ—…μ΄ 없을 경우 Suspenedμƒνƒœκ°€ λœλ‹€. 

이 μƒνƒœμ—μ„œ 앱은 λ©”λͺ¨λ¦¬μƒμ— μ˜¬λΌκ°€μžˆμ§€λ§Œ 아무 일도 ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— 배터리λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€. 

λ˜ν•œ OS에 μ˜ν•΄ λ©”λͺ¨λ¦¬ λΆ€μ‘±ν˜„μƒμ΄ λ°œμƒν•˜λ©΄ 이 μƒνƒœμ˜ 앱은 λ©”λͺ¨λ¦¬μ—μ„œ μ—†μ–΄μ§ˆ 수 있으며,

μ΄λŠ” λ”°λ‘œ μ•ŒλžŒμ„ ν•˜κ±°λ‚˜ ν•˜μ§„ μ•ŠλŠ”λ‹€.

 


App Delegate 객체의 λ©”μ†Œλ“œ 호좜

μ•±μ˜ 생λͺ…μ£ΌκΈ° μƒνƒœμ— λ”°λΌμ„œ 

AppDelegate 객체의 SceneDelegateμ—μ„œ νŠΉμ • λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜κ²Œ λœλ‹€.

 


1. Not Running μƒνƒœμΌ λ•Œ

application(_:willFinishLaunchingWithOptions:)

μœ„ λ©”μ†Œλ“œ μ•ˆμ—λŠ” 앱을 μ‹€ν–‰ν•  λ•Œ 졜초둜 μ‹€ν–‰ν•  μ½”λ“œλ₯Ό μž‘μ„±ν•˜λ©΄ μ’‹λ‹€.

ν•„μš”ν•œ μ£Όμš” 객체듀을 μƒμ„±ν•˜κ³  μ•± μ‹€ν–‰ μ€€λΉ„κ°€ λλ‚˜κΈ° 직전에 ν˜ΈμΆœλœλ‹€.

 

applicationDidFinishLaungching(_:)

μ•± 싀행을 μœ„ν•œ λͺ¨λ“  μ€€λΉ„κ°€ λλ‚œ ν›„ 화면이 μ‚¬μš©μžμ—κ²Œ 보여지기 직전에 ν˜ΈμΆœλœλ‹€. 

주둜 μ΄ˆκΈ°ν™” μ½”λ“œλ₯Ό 이곳에닀 μž‘μ„±ν•œλ‹€.

 

applicationWillTrerminate(_:)

앱이 μ’…λ£Œλ˜κΈ° 직전에 ν˜ΈμΆœλœλ‹€.


2. In - Active μƒνƒœμΌ λ•Œ

 

sceneWillEnterForeground(_:)

앱이 backgroundλ‚˜ not runningμ—μ„œ foreground둜 λ“€μ–΄κ°€κΈ° 직전에 ν˜ΈμΆœλœλ‹€.

λΉ„ν™œμ„±ν™” μƒνƒœλ₯Ό 거쳐 ν™œμ„±ν™” μƒνƒœκ°€ λœλ‹€.

 

sceneWillResignActive(_:)

App Swithcer λͺ¨λ“œ ( ν™ˆ λ°” μ“Έμ–΄ μ˜¬λ Έμ„ 경우 λ˜λŠ” ν™ˆ λ²„νŠΌ λͺ¨λΈ ν™ˆλ²„νŠΌ λ‘λ²ˆ λˆŒλ €μ„ 경우 )


3. Active μƒνƒœ 일 λ•Œ

sceneDidBecomeActive(_:)

앱이 λΉ„ν™œμ„±ν™” μƒνƒœμ—μ„œ ν™œμ„±μƒνƒœλ‘œ μ§„μž…ν•˜κ³  λ‚œ 직후 ν˜ΈμΆœλœλ‹€.

앱이 μ‹€μ œλ‘œ μ‚¬μš©λ˜κΈ° 전에, λ§ˆμ§€λ§‰μœΌλ‘œ μ€€λΉ„ν•  수 μžˆλŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.


4. Background μƒνƒœ 일 λ•Œ

sceneDidEnterBackground(_:)

앱이 background μƒνƒœλ‘œ 듀어갔을 λ•Œ ν˜ΈμΆœλœλ‹€.

suspened μƒνƒœκ°€ 되기 전에 μ€‘μš”ν•œ 데이터λ₯Ό μ €μž₯ν•˜λŠ” λ“± μ’…λ£Œν•˜κΈ° μ „ ν•„μš”ν•œ μž‘μ—…μ„ ν•œλ‹€.


5. Suspened μƒνƒœμΌ λ•Œ

λ”°λ‘œ ν˜ΈμΆœλ˜λŠ” λ©”μ†Œλ“œλŠ” μ—†μœΌλ©° background μƒνƒœμ—μ„œ νŠΉλ³„ν•œ μž‘μ—…μ΄ 없을 λ•Œ 이 μƒνƒœκ°€ λœλ‹€.

 

 

 

 


iOS 12와 iOS 13이상뢀터 λ™μž‘μ˜ 차이가 μžˆλŠ”λ°, λ¨Όμ € iOS 12 κΉŒμ§€μ˜ λ™μž‘μ„ μ‚΄νŽ΄λ³΄λ©΄,

 ~ iOS 12 : SceneDelegate μ—†μŒ

iOS 13 ~ : SceneDelegate 있음

 

 

iOS 12κΉŒμ§€μ˜ λ™μž‘ ( Scene을 지원 ν•˜μ§€ μ•ŠλŠ” 경우 )

 

iOS 12κΉŒμ§€λŠ” SceneDelegateκ°€ μ—†λ‹€. ( iOS 13λΆ€ν„° 쑴재 )

Sceneλ₯Ό μ§€μ›ν•˜μ§€ μ•ŠλŠ” 경우, λͺ¨λ“  생λͺ…μ£ΌκΈ° κ΄€λ ¨ μ΄λ²€νŠΈλ“€μ€ appDelegate에 μ „λ‹¬λœλ‹€.

각각의 μƒνƒœμ— μ ‘κ·Όν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ˜λŠ” 파일이 AppDelegate.swift 이닀. 

iOSμ•± ν”„λ‘œμ νŠΈλ₯Ό μƒμ„±ν•˜λ©΄ AppDelegate.swift 파일이 μžλ™μœΌλ‘œ μƒμ„±λ˜μ–΄ μžˆλ‹€.

 

AppDelegateλŠ” 이름 κ·ΈλŒ€λ‘œ μ•±κ³Ό μ‹œμŠ€ν…œμ˜ 연결을 μœ„ν•΄ ν•„μš”ν•œ delegate λ©”μ†Œλ“œλ₯Ό λ‹΄κ³  μžˆλ‹€.

 

 


iOS 13λΆ€ν„°μ˜ λ™μž‘ ( Sceneλ₯Ό μ§€μ›ν•˜λŠ” 경우 )

SceneDelegateλŠ” iOS13λΆ€ν„° μΆ”κ°€λœ ν΄λž˜μŠ€μ΄λ‹€.

SceneDelegateλŠ” UI 생λͺ…μ£ΌκΈ°λ₯Ό κ΄€λ¦¬ν•˜λŠ” ν΄λž˜μŠ€μ΄λ‹€. 

iOS12 κΉŒμ§€λŠ” ν•˜λ‚˜μ˜ 앱이 ν•˜λ‚˜μ˜ μœˆλ„μš°(Window)만 가지기 λ•Œλ¬Έμ—

AppDelegate ν΄λž˜μŠ€κ°€ UI 생λͺ…μ£ΌκΈ° κ΄€λ¦¬κΉŒμ§€ ν–ˆλ‹€.

 

ν•˜μ§€λ§Œ iOS13λΆ€ν„° ν•˜λ‚˜μ˜ 앱에 μ—¬λŸ¬ 개의 μœˆλ„μš°(Window)λ₯Ό λ™μ‹œμ— μ‚¬μš©ν•  수 있게 λ˜μ—ˆκΈ° λ•Œλ¬Έμ—

UI생λͺ…μ£ΌκΈ°λ₯Ό μ „λ‹΄ 관리해쀄 ν΄λž˜μŠ€κ°€ ν•„μš”ν•΄μ‘Œλ‹€. 

이λ₯Ό μœ„ν•΄ μΆ”κ°€λœ ν΄λž˜μŠ€κ°€ SceneDelegate이닀.

 

즉, Sceneλ₯Ό μ§€μ›ν•˜λŠ” 경우 Sceneλ³„λ‘œ λ³„λ„μ˜ 생λͺ…μ£ΌκΈ°λ₯Ό κ°€μ§€κ²Œ λœλ‹€.

scene ν•˜λ‚˜λŠ” λ””λ°”μ΄μŠ€μ—μ„œ λŒμ•„κ°€λŠ” μ•±μ˜ UIμΈμŠ€ν„΄μŠ€ ν•˜λ‚˜λ₯Ό λ‚˜νƒ€λ‚Έλ‹€.

ν•˜λ‚˜μ˜ 앱은 μ—¬λŸ¬κ°œμ˜ scene을 κ°€μ§ˆ 수 있으며, 이λ₯Ό κ°œλ³„μ μœΌλ‘œ λ„μš°κ±°λ‚˜ 숨길 수 μžˆλ‹€.

 

μ‚¬μš©μžλ‚˜ μ‹œμŠ€ν…œμ΄ μƒˆλ‘œμš΄ sceneλ₯Ό λ§Œλ“€μ–΄λ‹¬λΌκ³  μš”μ²­ν•˜λ©΄, UIKit은 이λ₯Ό λ§Œλ“€μ–΄ unattahced μƒνƒœλ‘œ λ§Œλ“ λ‹€.

μ‚¬μš©μžκ°€ μš”μ²­ν•œ scene은 곧μž₯ foreground inactive μƒνƒœλ₯Ό 거쳐 activeμƒνƒœκ°€ 되고,

μ‹œμŠ€ν…œμ΄ μš”μ²­ν•œ scene은 보톡 background μƒνƒœκ°€ λ˜μ–΄ 

이벀트 μ²˜λ¦¬ν•œ 뒀에 foreground둜 μ˜¬λΌμ˜¨λ‹€.

 

 


정리

 

[ μ•±μ˜ μƒνƒœ 5가지 ]

  • Not Running : 앱이 μ‹€ν–‰λ˜μ§€ μ•ŠλŠ” μƒνƒœ
  • Inactive         : 앱이 μ‹€ν–‰ 쀑인 μƒνƒœ, κ·ΈλŸ¬λ‚˜ μ•„λ¬΄λŸ° 이벀트λ₯Ό 받지 μ•ŠλŠ” μƒνƒœ
  • Active            : 앱이 싀행쀑이며 μ΄λ²€νŠΈκ°€ λ°œμƒν•œ μƒνƒœ
  • Background  : 앱이 λ°±κ·ΈλΌμš΄λ“œμ— μžˆλŠ” μƒνƒœ, κ·ΈλŸ¬λ‚˜ μ‹€ν–‰λ˜λŠ” μ½”λ“œκ°€ μžˆλŠ” μƒνƒœ
  • Suspened      : 앱이 λ°±κ·ΈλΌμš΄λ“œμ— 있고 μ‹€ν–‰λ˜λŠ” μ½”λ“œκ°€ μ—†λŠ” μƒνƒœ

 

 

[ delegate ν•¨μˆ˜λ₯Ό 톡해, 앱이 νŠΉμ • μƒνƒœμ—μ„œ λ™μž‘ν•˜λŠ” 둜직 κ΅¬ν˜„ ]


// 앱이 처음 μ‹œμž‘λ  λ•Œ μ‹€ν–‰
application (_: didFinishLaunching:)

// 앱이 activeμ—μ„œ inactive둜 이동될 λ•Œ μ‹€ν–‰ 
applicationWillResignActive :

// 앱이 background μƒνƒœμΌ λ•Œ μ‹€ν–‰
applicationDidEnterBackground:

// 앱이 backgroundμ—μ„œ foreground둜 이동될 λ•Œ μ‹€ν–‰
// (아직 foregroundμ—μ„œ 싀행쀑이진 μ•ŠμŒ )
applicationWillEnterForeground:

// 앱이 activeμƒνƒœκ°€ λ˜μ–΄ 싀행쀑일 λ•Œ
applicationDidBecomeActive:

// 앱이 μ’…λ£Œλ  λ•Œ μ‹€ν–‰
applicationWillTerminate: