代码之家  ›  专栏  ›  技术社区  ›  Jack Guo

RxSwift在闭包中正确地释放订阅

  •  0
  • Jack Guo  · 技术社区  · 7 年前

    我正在为Firebase身份验证函数编写一个包装器以返回 Observable 并添加其他 profileIncomplete 国家。它基本上首先检查用户是否登录,如果是,则检查用户的配置文件是否完整。下面是我的代码,我想知道是否可以订阅 Observable.create 如果是的话,在这种情况下,我该如何正确处理一次性用品?创建 DisposeBag 在封闭的内部?

    enum State {
        case loggedIn
        case profileIncomplete
        case notLoggedIn
    }
    
    func listenToAuthState() -> Observable<State> {
        return Observable.create { observable in
            let authStateHandle = Auth.auth().addStateDidChangeListener() { [weak self] (_, user) in
                guard let user = user else {
                    observable.onNext(.notLoggedIn)
                    return
                }
                let disposable = self?.listenToProfileCompleted(uid: user.uid).subscribe(onNext: { (completed) in
                    if completed {
                        observable.onNext(.loggedIn)
                        observable.onCompleted()
                    } else {
                        observable.onNext(.profileIncomplete)
                    }
                })
                // How to dispose the disposable???
            }
            return Disposables.create { 
                Auth.auth().removeStateDidChangeListener(authStateHandle) }
            }
    }
    
    func listenToProfileCompleted(uid: String) -> Observable<Bool> { ... }
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Shai Mishali    7 年前

    我认为订阅 Observable.create (或者在不同的subscribe块中)是一种代码味道。

    看来你有两个不同的问题。 stateChanged profileCompleted .

    我会把它们分成两种不同的方法 listenToAuthState 只负责反映 addStateDidChangeListener ,并有一个单独的 listenToProfileCompleted .

    这将让你有一个单独的“准备”(或者你想怎么称呼它)可以压缩两者。或者使用flatMap,如果在监听配置文件完成之前身份验证状态必须更改。

        2
  •  0
  •   SPatel mash    7 年前

    要释放资源,可以将其添加到DisposeBag。如下所示

    func listenToAuthState() -> Observable<State> {
        return Observable.create { observable in
            var disposeBag:DisposeBag! = DisposeBag()
            let authStateHandle = Auth.auth().addStateDidChangeListener() { [weak self] (_, user) in
                guard let user = user else {
                    observable.onNext(.notLoggedIn)
                    return
                }
                let disposable = self?.listenToProfileCompleted(uid: user.uid).subscribe(onNext: { (completed) in
                    if completed {
                        observable.onNext(.loggedIn)
                        observable.onCompleted()
                    } else {
                        observable.onNext(.profileIncomplete)
                    }
                }).disposed(by: disposeBag)
                // How to dispose the disposable???
            }
            return Disposables.create { 
                Auth.auth().removeStateDidChangeListener(authStateHandle)
                disposeBag = nil
            }
        }
    }
    
    推荐文章