TIL

[Sesac IOS] 43~44일차 TIL

43~44일차 수업을 정리한 글입니다.


Learned

반응형 프로그래밍 (Reactive Programming)

1) 개요

  • 객체지향, 함수형 프로그래밍 같은 프로그래밍 패러다임 중 하나로서,
    데이터의 흐름변경사항의 전파에 중점을 둔 선언적 프로그래밍 패러다임임.
  • 한 예시로, 엑셀의 스프레드 시트에서 C=A+B, D=C+A라는 연산을 선언해두고 A 또는 B의 값이 변경되면
    변경사항이 전파되어 C 의 값이 자동으로 변하고 그에 따라 D의 값도 변경되는 데이터의 흐름이 만들어짐.
  • 이런 관점을 프로그래밍에 활용해 프로그램을 설계하는 것이 반응형 프로그래밍이고
    이 반응형 프로그래밍과 어울리는 아키텍쳐 패턴이 MVVM임.
명령형 프로그래밍 vs 선언적 프로그래밍
명령형 프로그래밍은 시간 순서대로 작업을 처리할 방식(어떻게)을 결정하지만
선언적 프로그래밍은 어떤 작업을 할지(무엇을)를 선언해두고 처리 방식은 내부에서 결정됨.

2) 구현 방식(MVVM)

  • 뷰를 그리는(렌더링) 시점에 필요한 데이터를 불러오는 것(Pull)이 아니라,
    템플릿에 렌더링 작업을 선언해두고 데이터 변경이 감지될 때마다
    바인딩 되어있는 템플릿에 값을 전달(Push)하여 선언한 작업을 수행하는 방식 
  • 뷰를 그리는 것 뿐 아니라 비즈니스 로직에도 같은 방식이 사용될 수 있음.
// 데이터 모델
class Observable<T> { 
    private var listener: ((T) -> Void)?
    // 값이 변경될 때마다 변경사항 전파
    var value: T {
        didSet { listener?(value) }
    }
    // 템플릿 바인딩
    func bind(_ closure: @escaping (T) -> Void) {
        closure(value)
        listener = closure
    }
    
}
// 비즈니스 로직을 처리할 뷰 모델
class LoginViewModel {

    var password: Observable<String> = Observable("")
    var isValid = Observable(false)
    
    func checkValidation() {
        isValid.value = password.value.count >= 8 ? true : false
    }
}
class LoginViewController: UIViewController {
    
    @IBOutlet weak var passwordTextfield: UITextField!
    @IBOutlet weak var logginButton: UIButton!
    
    let viewModel = LoginViewModel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 렌더링 작업 선언
        viewModel.isValid.bind { bool in
            self.logginButton.isEnabled = bool
            self.logginButton.backgroundColor = bool ? .red : .lightGray
        }
    }
    
    @IBAction func passwordTextfieldDIdChanged(_ sender: UITextField) {
        viewModel.password.value = sender.text!
        viewModel.checkValidation()
    }
}

비동기 프로그래밍

1) 중요성

  • iOS 앱에서 서버 네트워킹 로직은 대부분 비동기로 되어있기 때문에 서버의 응답이
    언제 올지 예측할 수 없음. → 즉 작업의 순서가 보장되지 않음.
  • 또한 UI를 통해 상호작용하는 사용자의 행동을 예측할 수 없기 때문에
    비동기 작업을 다루는 것은 매우 중요함.
따라서 반응형 프로그래밍이 중요한 이유는 비동기 프로그래밍을 잘 하기 위해서임.

2) Swift의 비동기 프로그래밍

  • GCD, OperationQueue, Async/Await가 있음.
  • GCD(Grand Central Dispatch)
    • DispatchQueue.main(global).async 메서드로 비동기 작업 실행
    • 메인 스레드에서 main 큐로 sycn 작업을 보낼 시 교착상태에 빠짐.
      보낸 작업이 끝날때까지 대기하는데 이미 수행중인 작업때문에 보낸 작업이 수행되지 않음.
    • 메인 스레드에서 global 큐로 sycn 작업을 보낼 시 메인 스레드는
      어차피 해당 작업이 끝날때 까지 대기해야 하므로 메인 스레드에서 작업을 수행함.
    • QOS(Quaility Of Service) 로 보낸 작업의 우선순위를 설정할 수 있음.
  • DispatchGroup
    • 여러 작업을 묶어 하나의 단위처럼 모니터링할 수 있는 클래스임.
    • 그룹에 포함된 작업들의 순서를 정할 수는 없지만 모든 작업이 완료된 시점을
      알리고 특정 클로저를 실행할 수 있음.
    • 네트워크 요청같은 비동기 작업을 그룹으로 묶으면 서버 응답과 관계없이
      모든 요청이 끝난 시점을 알려주기 때문에 사용에 유의해야 함.
    • enter(), leave() 메서드로 그룹의 레퍼런스 카운트를 수동으로 증가, 감소시킬 수 있음.
      → 네트워크 요청 시 enter, 응답을 받은 후 leave하는 방식 등으로 응용할 수 있음.
  • Race Condition
    • 다수의 비동기 작업들이 동시에 수행될 때 여러 스레드에서
      하나의 공유 자원(전역 변수 등)에 접근하여 발생하는 경쟁 상태를 의미함.
    • Xcode 메뉴 상단 Product -> Scheme -> Edit Scheme 에서
      런타임 중 raceCondition 감지할 수 있게 설정할 수 있음. (Thread Sanitizer)

 


이상입니다.

'TIL' 카테고리의 다른 글

[Sesac IOS] 46일차 TIL  (0) 2022.09.09
[Sesac IOS] 45일차 TIL  (0) 2022.09.07
[Sesac IOS] 42일차 TIL  (0) 2022.08.31
[Sesac IOS] 41일차 TIL  (2) 2022.08.31
[Sesac IOS] 40일차 TIL  (0) 2022.08.31