为什么RxSwift订阅只在第一次启动viewWillAppear中运行一次?

时间:2017-08-23 07:00:42

标签: ios swift observable rx-swift

我在viewWillAppear中写了一个订阅 但它也在首次启动应用程序中运行一次 当我推送到另一个viewcontroller时,我使用dispose()。
然后我回到第一个viewcontroller,我的订阅功能在viewWillAppear中运行。
我的rx订阅有什么问题?

var listSubscribe:Disposable?

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    listSubscribe = chatrooms.notifySubject.subscribe({ json in
        print("*1") //just print once in first launch
        self.loadContents()
    })
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    let controllers = tabBarController?.navigationController?.viewControllers
    if (controllers?.count)! > 1 {
        listSubscribe?.dispose()
    }
}

2 个答案:

答案 0 :(得分:0)

RxSwift文档说"Note that you usually do not want to manually call dispose; this is only an educational example. Calling dispose manually is usually a bad code smell."

通常,你应该做这样的事情 -

    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        whatever.subscribe(onNext: { event in
        // do stuff
        }).disposed(by: self.disposeBag)

    }

至于你的问题,我相信你不需要重新订阅,因为你的订阅将会存在并且“通知主题”。只要有任何更新,我们都会向您发送更新。

答案 1 :(得分:0)

也许你可以获得viewWillAppear和类似功能的反应性实现?并忘记手动一次性用品处理...例如,您的UIViewController init将包含以下内容:

rx.driverViewState()
    .asObservable()
    .filter({ $0 == .willAppear })
    .take(1) // if you need only first viewWillAppear call
    .flatMapLatest({ _ in
        // Do what you need
    })

driverViewState的实施:

public extension UIViewController {

    public enum ViewState {
        case unknown, didAppear, didDisappear, willAppear, willDisappear
    }
}

public extension Reactive where Base: UIViewController {

    private typealias _StateSelector = (Selector, UIViewController.ViewState)
    private typealias _State = UIViewController.ViewState

    private func observableAppearance(_ selector: Selector, state: _State) -> Observable<UIViewController.ViewState> {
        return (base as UIViewController).rx
            .methodInvoked(selector)
            .map { _ in state }
    }

    func driverViewState() -> Driver<UIViewController.ViewState> {
        let statesAndSelectors: [_StateSelector] = [
            (#selector(UIViewController.viewDidAppear(_:)), .didAppear),
            (#selector(UIViewController.viewDidDisappear(_:)), .didDisappear),
            (#selector(UIViewController.viewWillAppear(_:)), .willAppear),
            (#selector(UIViewController.viewWillDisappear(_:)), .willDisappear)
        ]
        let observables = statesAndSelectors
            .map({ observableAppearance($0.0, state: $0.1) })
        return Observable
            .from(observables)
            .merge()
            .asDriver(onErrorJustReturn: UIViewController.ViewState.unknown)
            .startWith(UIViewController.ViewState.unknown)
            .distinctUntilChanged()
    }
}
相关问题