ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [RxSwift] Subscribe, Bind, Driver
    iOS 2023. 6. 25. 17:20

    오늘은 Subscribe, Bind, Driver의 차이점에 대해 정리해보려 합니다.

     

    평소 rx로 개발을 하면서 아무 생각없이 복붙을 하면서 했었는데,

    어떤 차이점이 있는지 알아보고 상황에 맞게 사용해보려 합니다.

     

     


    1. Subscribe

     

    아래 코드 내용을 확인해보면, onNext, onError, onCompleted, onDisposed 4가지의 parameter 가 존재하는 것을 알 수 있습니다.

    말그대로 구독한다는 개념이여서 무언가가 변하면 그 값을 받아오는 역할을 합니다.

     

        public func subscribe(
            onNext: ((Element) -> Void)? = nil,
            onError: ((Swift.Error) -> Void)? = nil,
            onCompleted: (() -> Void)? = nil,
            onDisposed: (() -> Void)? = nil
        ) -> Disposable {
                let disposable: Disposable
                
                if let disposed = onDisposed {
                    disposable = Disposables.create(with: disposed)
                }
                else {
                    disposable = Disposables.create()
                }
                
                #if DEBUG
                    let synchronizationTracker = SynchronizationTracker()
                #endif
                
                let callStack = Hooks.recordCallStackOnError ? Hooks.customCaptureSubscriptionCallstack() : []
                
                let observer = AnonymousObserver<Element> { event in
                    
                    #if DEBUG
                        synchronizationTracker.register(synchronizationErrorMessage: .default)
                        defer { synchronizationTracker.unregister() }
                    #endif
                    
                    switch event {
                    case .next(let value):
                        onNext?(value)
                    case .error(let error):
                        if let onError = onError {
                            onError(error)
                        }
                        else {
                            Hooks.defaultErrorHandler(callStack, error)
                        }
                        disposable.dispose()
                    case .completed:
                        onCompleted?()
                        disposable.dispose()
                    }
                }
                return Disposables.create(
                    self.asObservable().subscribe(observer),
                    disposable
                )
        }

     

     

    2. Bind

     

    위에서 봤던 Subscribe와 달리 parameter로 onNext만 가지고 있는 것이 차이점입니다.

    그래서 에러 처리가 불가능하고, 간단하게 변경된 값을 전달만 하게되죠.  (onNext만 하는 Subscribe와 동일함)

     

    단점으로는, observer가 추가될때마다 새로운 스트림이 발생합니다.

    옵저버가 늘어날때마다 스트림이 늘어나기 때문에 리소스적으로 낭비되게 됩니다.

     

    public func bind(onNext: @escaping (Element) -> Void) -> Disposable {
            self.subscribe(onNext: onNext,
                           onError: { error in
                            rxFatalErrorInDebug("Binding error: \(error)")
                           })
        }

     

     

    3. Drive

     

    여기서도 우선 parameter를 확인해보면 onError 가 빠져있는 것을 보니 에러처리가 불가능하겠네요!

    추가적으로 MainScheduler 라고 적혀있기 때문에 메인스레드에서 동작하는 것을 보장하는 것이 특징입니다.

     

    Bind와 다르게 하나의 스트림을 공유하기 때문에 리소스 측면에서 효율적입니다.

    public func drive(
            onNext: ((Element) -> Void)? = nil,
            onCompleted: (() -> Void)? = nil,
            onDisposed: (() -> Void)? = nil
        ) -> Disposable {
            MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage)
            return self.asObservable().subscribe(onNext: onNext, onCompleted: onCompleted, onDisposed: onDisposed)
        }

     

    근데 Driver 사용 시 고려해야 할 사항이 있습니다.

    asDriver()를 통해 Drive Trait 을 부여해줘야 사용할 수 있습니다.

     

    그래서 subject 타입은 error 나 completed 를 발생시키기 때문에, .asDriver(error: ) 이런식으로 변환하고,

    Relay 타입은 error나 completed 를 발생시키지 않기 때문에, 그냥 .asDriver() 이렇게 변환하면 된다.

     

     


     

    즉, UI 관련 작업을 하려면 Relay + Drive 조합

    값을 저장하고 사용하려면 Subject + Subscirbe 조합

    'iOS' 카테고리의 다른 글

    신입 iOS 개발자 1년간의 회고  (2) 2023.09.30
    [RxSwift] Subject, Relay  (0) 2023.05.31
    [iOS] isUserInteractionEnabled  (0) 2023.02.28
    [iOS] Clean Architecture  (0) 2023.01.22

    댓글

Designed by Tistory.