티스토리 뷰

728x90

 

오늘은 개인 프로젝트에 MVVM을 적용해보면서

dataBinding을 할때

Observable이라는 class의 동작 방식을 공부해 보려고 합니다.

 

가즈아!

 


아래는 MVVM을 사용하고 데이터 바인딩을 해보셨다면 한번쯤 보셨을 코드입니다.

 

이런형태가 있구나 하면서 보세요 

설명은 아래서 !

class Observable<T> {
    // 3
    var listener: ((T) -> Void)?
    
    // 2
    var value: T {
        didSet {
            self.listener?(value)
        }
    }
    // 1
    init(_ value: T) {
        self.value = value
    }
    
    // 4
    func bind(listener: @escaping (T) -> Void) {
        listener(value)
        self.listener = listener
    }
}

 

목적

Rx나 Combine을 사용하지 않았을때

ViewViewModel 사이에서 지정된 프로퍼티의 값이 바뀔때마다 View에 변화를 주고싶을때 사용 합니다.

데이터 바인딩 이라고 해요.

 

이제부터 하나씩 뜯어봅시다.

 

데이터 바인딩을 할때 사용되는 로직의 예는 아래와 같습니다.

 

(상황)

ViewModel의 titleLabel의 값이 바뀌면, ViewController에 있는 titleLabel을 바꿔주려함. (View는 ViewModel 바라기기 때문)

 

ViewController

class ViewController: UIViewController {

  private lazy var titleLabel: UILabel = {
        let label = UILabel()
        return label
   }()

  let viewModel = ViewModel()
  
  // 데이터 바인딩 하는곳
  override func viewDidLoad() {
      viewModel.titleLabel.bind { [weak self] text in
          DispatchQueue.main.async {
            self?.titleLabel.text = text
          }
      }
  }
  
}

 

ViewModel

class ViewModel {

    let titleLabel: Observable<String> = Observable("")

 

 

이제 Observable을 볼게요.

주석으로 동작하는 순서 설명을 남겨놨습니다.

 

 

Observable

class Observable<T> {

    // 1. 값을 value에 초기화 합니다.
    init(_ value: T) {
        self.value = value
    }
    
}

 

class Observable<T> {

    // 3. listener가 호출되면 2번에서 받은 값을 전달합니다.
    var listener: ((T) -> Void)?
    
    // 2. 값이 바뀐 직후, listener에 해당 값을 전달합니다.
    var value: T {
        didSet {
            self.listener?(value)
        }
    }

    init(_ value: T) {
        self.value = value
    }
    
}

 

class Observable<T> {

    var listener: ((T) -> Void)?

    var value: T {
        didSet {
            self.listener?(value)
        }
    }

    init(_ value: T) {
        self.value = value
    }
    // VC에서 bind가 호출되면
    func bind(listener: @escaping (T) -> Void) {
        listener(value) // 4. listener에 저장 했던 값 전달
        self.listener = listener // 5. 추후 didSet에서 실행하기 위해 listener의 값을 self.listener에 할당
    }

}

 

 

 

 

728x90