관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - Swift] RxSwit의 생성자, Observable의 deffered 사용 방법 본문

RxSwift/RxSwift 기본

[iOS - Swift] RxSwit의 생성자, Observable의 deffered 사용 방법

jake-kim 2022. 9. 4. 17:49

Observable의 Deferred

  • 보통 어떤 작업을 wrapping할때 Observable<Type>.create()를 사용하지만, deferred를 사용하는 방법이 존재
  // Observable<Int>.create 사용 예제
  
  // stored propoerty
  let aObservable = Observable<Int>.create { observer in
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
      observer.onNext(1)
      observer.onCompleted()
    }
    
    return Disposables.create()
  }
  
  // computed proprety
  var bObservable: Observable<Int> {
    .create { observer in
      observer.onNext(10)
      observer.onCompleted()
      return Disposables.create()
    }
  }
  • deferred는 subscribe하기 전까지 deferred 구현부에 있는 Observable의 생성을 지연시키고 있는 코드
    • 메모리 관점에서 구독할때 안에 구현부가 메모리에 로드되며 메모리 효율에 좋은 코드
    • 단, Observable.create와 실행 시 동작 차이는 존재 x
  // stored propoerty
  let bDeferred = Observable<Int>.deferred {
    .just(2)
  }
  
  // computed propoerty
  var cDeferred: Observable<Int> {
    .deferred {
      .just(3)
    }
  }
  • Deferred의 단점
    • Deferred는 구독이되는 시점에 메모리에 Observable을 생성하는 코드가 올라오기 때문에 빠르게 Observable을 구독하여 사용하고 싶은경우 성능에 안좋은 영향을 미칠 수 있음
    • 대부분은 Deferred를 사용하지 않으면서 메모리 효율을 내고 싶을때만 사용할것

Deferred 를 사용하는 경우

  • 아래처럼 항상 앱을 생성할때마다 호출하는 코드가, 아닌 경우 Observable을 생성하는 코드가 메모리에 굳이 올라와 있지 않아도 되는 코드이므로 deferred를 사용

* 구체적인 관련 코드는 이전 포스팅 글인, Observable로 Wrapping하여 권한 요청 방법 글 참고

func requestLocation() -> Observable<CLAuthorizationStatus> {
  return Observable<CLAuthorizationStatus>
    .deferred { [weak self] in
      guard let ss = self else { return .empty() }
      ss.locationManager.requestWhenInUseAuthorization()
      return ss.locationManager.rx.didChangeAuthorization
        .map { $1 }
        .filter { $0 != .notDetermined }
        .do(onNext: { _ in ss.locationManager.startUpdatingLocation() })
        .take(1)
    }
}​

 

Comments