🍎 iOS & Swift

비동기 ν”„λ‘œκ·Έλž˜λ°μ΄λž€?

taeeekki 2022. 8. 20. 02:12

듀어가기전에

Rx, Reactive Programming이 비동기 ν”„λ‘œκ·Έλž˜λ°μ„ μž˜ν•˜κΈ° μœ„ν•œ λ…Έλ ₯이라고 이전 μ‹œκ°„(Reactive Programming 편)에 μ΄μ•ΌκΈ°ν–ˆλŠ”λ° 그럼 비동기? 비동기 ν”„λ‘œκ·Έλž˜λ°μ΄ λ¬΄μ—‡μΌκ°€μš”? κ°„λ‹¨ν•˜κ²Œ μ‚΄νŽ΄λ³΄λ„λ‘ ν•˜μ£ .

 


 

비동기 ν”„λ‘œκ·Έλž˜λ°?

iOS 앱은 λ‹€μŒκ³Ό 같은 μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  • λ²„νŠΌ νƒ­(클릭)에 λ°˜μ‘ν•˜κΈ°
  • ν‚€λ³΄λ“œλ₯Ό ν…μŠ€νŠΈ ν•„λ“œλ‘œ μ• λ‹ˆλ©”μ΄μ…˜ν•˜λ©΄ ν¬μ»€μŠ€κ°€ 사라짐
  • μΈν„°λ„·μ—μ„œ 큰 사진 λ‹€μš΄λ‘œλ“œ → λ‹€μš΄λ‘œλ“œ 쀑에 λ‹€λ₯Έ μž‘μ—…μ„ μˆ˜ν–‰
  • 데이터 λΉ„νŠΈλ₯Ό λ””μŠ€ν¬μ— μ €μž₯
  • μ˜€λ””μ˜€ μž¬μƒ

좜처 : Raywenderich - μ—¬κΈ° ν΄λ¦­

ν•œ 번 생각을 해보면 각각의 μž‘μ—…λ“€μ€ μ„œλ‘œμ˜ 싀행을 μ°¨λ‹¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μ„œλ‘œ λ‹€λ₯Έ μŠ€λ ˆλ“œμ—μ„œ μ„œλ‘œ λ‹€λ₯Έ μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆλ„λ‘ iOSλŠ” λ‹€μ–‘ν•œ μ’…λ₯˜μ˜ APIλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

 

 


 

Apple의 Cocoa and UIKit asynchronous APIs (비동기 API)

ν•œ 번쯀 μ‚¬μš©ν•΄λ΄€κ±°λ‚˜ λ“€μ–΄λ³Έ λ‚΄μš©μΌ κ²ƒμž…λ‹ˆλ‹€.
Apple은 iOS SDKμ—μ„œ 비동기식 μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ„λ‘ λ‹€μŒκ³Ό 같은 방법듀을 μ œκ³΅ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

  • NotificationCenter
  • Delegate Pattern
  • Grand Central Dispatch(GCD)
  • Closures
  • Combine - iOS13λΆ€ν„° μ΄μš©κ°€λŠ₯ν•œ API

λŒ€λΆ€λΆ„μ˜ ν΄λž˜μŠ€λ“€μ€ 개발자의 μ˜λ„μ™€ λ‹€λ₯΄κ²Œ λΉ„λ™κΈ°μ μœΌλ‘œ μˆ˜ν–‰ν•˜κ³ ,
UI μš”μ†Œμ˜ κ²½μš°λ„ 본질적으둜 λΉ„λ™κΈ°μ μž…λ‹ˆλ‹€.

κ°œλ°œμžκ°€ μ•± μ½”λ“œλ₯Ό μž‘μ„±ν–ˆμ„ λ•Œ, 맀번 μ–΄λ–€ μˆœμ„œλ‘œ μž‘λ™ν•œλ‹€κ³  κ°€μ •ν•˜λŠ” 것은 λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€.
μ‚¬μš©μžμ™€μ˜ μΈν„°λž™μ…˜, λ„€νŠΈμ›Œν‚Ή, 이벀트 λ“±μ˜ μ™ΈλΆ€ μš”μΈμ— μ˜ν•΄ μ™„μ „νžˆ λ‹€λ₯Έ μˆœμ„œλ‘œ 싀행될 수 μžˆμŠ΅λ‹ˆλ‹€.

 

 


 

비동기 ν”„λ‘œκ·Έλž˜λ°μ„ ν•˜λ‹€ 보면 κ°–κ²Œ λ˜λŠ” 문제 μ˜μ‹

πŸ—£ ν΄λž˜μŠ€μ™€ ν•¨μˆ˜μ˜ μž‘λ™ μˆœμ„œλ₯Ό 보μž₯ν•  수 μ—†μŠ΅λ‹ˆλ‹€!

μ–΄λ–€ 것이 λ¨Όμ € 리턴될지, μž‘λ™ μˆœμ„œλ₯Ό 보μž₯ν•  수 μ—†κΈ° λŒ€λ¬Έμ— μ½”λ“œλ₯Ό μž‘μ„±ν•˜λ‹€λ³΄λ©΄ μžμ—°μŠ€λŸ½κ²Œ λŽμŠ€κ°€ λ³΅μž‘ν•΄μ§€λŠ” μ½”λ“œκ°€ λ§Œλ“€μ–΄μ§‘λ‹ˆλ‹€.

 

μ½”λ“œ μ˜ˆμ‹œ)

IBAction func onLoad() {
    editView.text = ""
    self.setVisibleWithAnimation(self.activityIndicator, true)
    
    downloadJson(MEMBER_LIST_URL) { json in
        self.editView.text = json
        self.setVisibleWithAnimation(self.activityIndicator, false)
        
        self.downloadJson(MEMBER_LIST_URL) { json in
            self.editView.text = json
            self.setVisibleWithAnimation(self.activityIndicator, false)
        }
        
        self.downloadJson(MEMBER_LIST_URL) { json in
            self.editView.text = json
            self.setVisibleWithAnimation(self.activityIndicator, false)
        }
        
        self.downloadJson(MEMBER_LIST_URL) { json in
            self.editView.text = json
            self.setVisibleWithAnimation(self.activityIndicator, false)
        }
        
        self.downloadJson(MEMBER_LIST_URL) { json in
            self.editView.text = json
            self.setVisibleWithAnimation(self.activityIndicator, false)
        }
    }
}

 

πŸ—£ μ²˜λ¦¬ν•΄μ•Ό ν•  μž‘μ—…μ΄ λ§Žμ•„μ§ˆ 경우 μ½”λ“œκ°€ λ³΅μž‘ν•΄μ§„λ‹€.

Swift κ°œλ°œμ„ ν•˜λ‹€λ³΄λ©΄ Escaping Closure λ° Completion Handlerλ₯Ό μ‚¬μš©ν•˜λŠ” 비동기 ν”„λ‘œκ·Έλž˜λ°μ„ 많이 ν•˜κ²Œ λ©λ‹ˆλ‹€.
λ§Žμ€ 비동기 μž‘μ—…, 였λ₯˜ 처리, 비동기 호좜 κ°„μ˜ μ œμ–΄ 흐름이 λ³΅μž‘ν•  λ•Œ λ¬Έμ œκ°€ μƒκΈ°κ²Œ λ©λ‹ˆλ‹€.

기본적으둜 Appleμ—μ„œ μ œκ³΅ν•˜λŠ” API(ex. GCD)λ₯Ό μ‚¬μš©ν•΄μ„œ 비동기 ν”„λ‘œκ·Έλž˜λ°μ„ ν•˜λ©΄μ„œλ„ μ—¬λŸ¬ λ¬Έμ œμ μ„ 느끼게 되죠.
DispatchQueueλ‚˜ ν΄λ‘œμ €λ§ŒμœΌλ‘œλ„ 비동기 ν”„λ‘œκ·Έλž˜λ°μ΄ κ°€λŠ₯은 ν•˜μ§€λ§Œ μ²˜λ¦¬ν•΄μ•Όν•  μž‘μ—…μ΄ λ§Žμ•„μ§ˆ 경우 μ½”λ“œκ°€ 맀우 λ³΅μž‘ν•΄μ§€λŠ” λ¬Έμ œκ°€ μƒκΈ°κ²Œ λ©λ‹ˆλ‹€.

 

πŸ—£ 비동기 μž‘μ—…μ˜ 경우 μ¦‰μ‹œ κ²°κ³Όκ°€ λ‚˜μ˜€μ§€ μ•ŠλŠ”λ‹€.

λ‚˜μ€‘μ— 데이터가 였면 μ²˜λ¦¬ν•˜λŠ” λ°©μ‹μœΌλ‘œ μ½”λ“œλ₯Ό 짜고 μ‹ΆμŠ΅λ‹ˆλ‹€. Completion Handler 말고 Return κ°’μœΌλ‘œ μ²˜λ¦¬ν•˜κ³  싢은거죠.
그것을 κ°€λŠ₯ν•˜κ²Œ ν•΄μ£ΌλŠ” 것이 Rx의 Observableμž…λ‹ˆλ‹€. (μš°λ¦¬λŠ” RxSwiftμ—μ„œμ˜ Observable 이겠죠?)

 

 

λ‚˜μ€‘μ— λ‹€μ‹œ μ•Œμ•„λ³΄κ² μ§€λ§Œ 정리해보면 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

Rx(Swift)λž€ λΉ„λ™κΈ°μ μœΌλ‘œ μƒκΈ°λŠ” 데이터λ₯Ό completion 같은 closure둜 μ „λ‹¬ν•˜λŠ” 것이 μ•„λ‹ˆλΌ return κ°’μœΌλ‘œ μ „λ‹¬ν•˜κΈ° μœ„ν•΄μ„œ λ§Œλ“€μ–΄μ§„ μœ ν‹Έλ¦¬ν‹°(API)이닀.

 


 

비동기 λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ ν•„μš”ν•œ 4κ°€μ§€

λͺ¨λ“  λΉ„λ™κΈ°μž‘μ—…μ„ μ²˜λ¦¬ν•˜λŠ” λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ ν•„μš”ν•œ 것은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

λ‚˜λ¨Έμ§€ ν•­λͺ©μ— λŒ€ν•œ μžμ„Έν•œ λ‚΄μš©μ€ μ—¬κΈ°μ—μ„œ μ½μ–΄λ³΄μ„Έμš”.
μš°λ¦¬λŠ” 이 μ€‘μ—μ„œ μŠ€λ ˆλ“œ 관리에 μ§‘μ€‘ν•΄λ΄…μ‹œλ‹€.

  • λͺ…μ‹œμ  μ‹€ν–‰(Explicit execution)
  • μƒˆλ‘œμš΄ μŠ€λ ˆλ“œμ—μ„œ μž‘μ—…μ„ μ‹œμž‘ν•˜λ©΄ 그것을 μ»¨νŠΈλ‘€ν•  수 μžˆμ–΄μ•Ό ν•œλ‹€.
  • μ‰¬μš΄ μŠ€λ ˆλ“œ 관리(Easy thread management)
  • πŸ—£
    λΉ„λ™κΈ°μž‘μ—…μ—μ„œ μŠ€λ ˆλ“œ 관리가 핡심이닀.
    λ°±κ·ΈλΌμš΄λ“œ μž‘μ—… λ„μ€‘μ΄λ‚˜ μž‘μ—…μ΄ λλ‚œ ν›„, (예λ₯Ό λ“€λ©΄ λ„€νŠΈμ›Œν‚Ή 처리 ν›„)
    λ©”μΈμŠ€λ ˆλ“œμ—μ„œ UIλ₯Ό μ—…λ°μ΄νŠΈν•΄μ•Ό ν•  λ•Œκ°€ μžˆλ‹€.
    
    이 λ•Œ μŠ€λ ˆλ“œ(λ°±κ·ΈλΌμš΄λ“œ) → λ‹€λ₯Έ μŠ€λ ˆλ“œ(메인)둜 μž‘μ—…μ„ λ„˜κ²¨μ•Ό ν•˜λŠ”λ°
    μŠ€λ ˆλ“œλ₯Ό μ‰½κ²Œ μ „ν™˜ν•˜κ³  ν•„μš”ν•œ 경우 λ‹€λ₯Έ μŠ€λ ˆλ“œλ‘œ μž‘μ—…μ„ λ„˜κΈΈ 수 μžˆμ–΄μ•Ό ν•œλ‹€.
    
  • μ‰¬μš΄ ꡬ성λ ₯(Easily composable)
  • λΉ„λ™κΈ°μž‘μ—…μ„ μƒμ„±ν•˜κ³  μ‹œμž‘ν•˜λ©΄ 그것은 λ‹€λ₯Έ μ–΄λ–€ μŠ€λ ˆλ“œμ— μ˜μ‘΄ν•˜μ§€ μ•Šκ³  μž‘μ—…μ΄ 끝날 λ•ŒκΉŒμ§€ λ…λ¦½μ μœΌλ‘œ μœ μ§€ν•˜λŠ” 것이 μ’‹λ‹€.
  • λΆ€μž‘μš© μ΅œμ†Œν™”(Minimum the sid effects)
  • λ©€ν‹° μŠ€λ ˆλ“œκ°€ μˆ˜ν–‰λ˜λŠ” λ™μ•ˆ μŠ€λ ˆλ“œ μ„œλ‘œ κ°„ 영ν–₯을 λΌμΉ˜λŠ” λΆ€μž‘μš©μ„ μ΅œμ†Œν™”ν•΄μ•Όν•œλ‹€.

 


 

마무리 μ‹œκ°„

비동기 ν”„λ‘œκ·Έλž˜λ°

μš°λ¦¬λŠ” κ°œλ°œμ„ ν•˜κ²Œ 될 λ•Œ ν•„μˆ˜λΆˆκ°€κ²°ν•˜κ²Œ 비동기 ν”„λ‘œκ·Έλž˜λ°μ„ ν•˜κ²Œ λ©λ‹ˆλ‹€. λ„€νŠΈμ›Œν¬ ν†΅μ‹ λ§Œμ„ 보더라도 μš°λ¦¬λŠ” μ„œλ²„μ—μ„œ 데이터λ₯Ό λ°›μ•„μ˜¬ λ•Œ κ²°κ³Ό 데이터가 μ–Έμ œ 도착할 μ§€ λͺ¨λ₯΄κ³ , κ²°κ³Ό 데이터가 λ„μ°©ν•˜λ©΄ μ–΄λ–€ 처리λ₯Ό ν•˜κ²Œ 되죠? 이처럼 μš°λ¦¬λŠ” μž‘μ—…μ— λŒ€ν•œ μˆœμ„œλ₯Ό 항상 보μž₯ν•  수 μ—†μŠ΅λ‹ˆλ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— 비동기적 ν”„λ‘œκ·Έλž˜λ°μ΄ ν•„μš”ν•œ κ²ƒμž…λ‹ˆλ‹€.

문제점

비동기적 ν”„λ‘œκ·Έλž˜λ°μ„ ν•  λ•Œμ— 보톡 Closure와 Completion handlerλ₯Ό μ΄μš©ν•΄μ„œ μ½”λ“œλ₯Ό μž‘μ„±ν•©λ‹ˆλ‹€. 이 경우 μž‘μ—…μ΄ λ§Žμ•„μ§ˆ 경우 μ½”λ“œκ°€ λ³΅μž‘ν•΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. 리턴값을 λ°›μ•„μ„œ μ²˜λ¦¬ν•˜κ³  μ‹Άλ‹€λŠ” 생각이 μžμ—°μŠ€λŸ½κ²Œ λ“€κ²Œ λ˜λŠ”λ° 이 λ•Œ μš°λ¦¬λŠ” RxSwiftλ₯Ό μ΄μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μš”μ•½

비동기 ν”„λ‘œκ·Έλž˜λ°μ΄λž€ 각각의 μŠ€λ ˆλ“œκ°€ λ…λ¦½μ μœΌλ‘œ 자기 μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 것을 μ˜λ―Έν•˜κ³ , κ·Έλ ‡κΈ° λ•Œλ¬Έμ— μž‘μ—… μˆœμ„œλ₯Ό 보μž₯ν•  수 μ—†λ‹€. 
κ°„λ‹¨ν•˜κ²Œ λ§ν•˜λ©΄ μ–΄λ–€ μŠ€λ ˆλ“œκ°€ λ¨Όμ € μž‘μ—…μ„ λ§ˆμΉ μ§€ μ•Œ 수 μ—†λ‹€λŠ” 것이닀.

 


 

레퍼런슀

https://gaki2745.github.io/swift/2019/10/13/Swift-RxSwift-01/

https://zeddios.tistory.com/1230

https://duda-programming.tistory.com/48

https://haningya.tistory.com/112

https://dev-daddy.tistory.com/25