2017-08-23 3 views
0

J'écris un abonnement dans viewWillAppear.
Mais il fonctionne également une fois dans la première application de lancement.
Lorsque j'appuie sur un autre viewcontroller, j'utilise dispose().
Ensuite, je suis de retour dans le premier viewcontroller, ma fonction d'abonnement dans viewWillAppear ne fonctionne pas.
Quel est le problème avec mon abonnement rx?Pourquoi RxSwift Subscribe vient de s'exécuter une fois dans First launch viewWillAppear?

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() 
    } 
} 

Répondre

0

documentation RxSwift dit "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."

Normalement, vous devriez faire quelque chose comme ça -

let disposeBag = DisposeBag() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

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

    } 

Quant à votre question, je crois que vous ne avez pas besoin de réabonner parce que vous L'abonnement sera actif et 'notifySubject' vous enverra des mises à jour dès qu'il y en aura.

0

Peut-être que vous pouvez obtenir une implémentation réactive de viewWillAppear et des fonctions similaires? Et oublier la manutention manuelle ... Par exemple disposables votre UIViewControllerinit contiendra quelque chose comme ceci:

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

et la mise en œuvre de 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() 
    } 
}