2015-11-24 4 views
3

У меня есть BehaviorSubject с именем createObservable в моей модели. И мой контроллер просмотра подписывается.rxswift ошибка ручки проблема

viewModel!.createObservable.subscribe(onNext: {[unowned self] (obj:PassbookModelType?) -> Void in 
    if let _ = obj{ 
     self.dismissVC() 
    } 
}, onError: { (error) -> Void in 
    print(error) 
}).addDisposableTo(self.dispose) 

У меня есть функция с именем saveObject() также в модели представления. Если я нажму на правый пункт навигационной панели, он будет испущен. И ошибка будет отправлена ​​на наблюдателя createObservable.

func saveObject(){ 
    ``````` 
    ``````` 
    if condition { 
     createObservable.on(Event.Next(model)) 
     createObservable.onCompleted() 
    }else{ 
     createObservable.onError(MyError.someError) 
    } 
} 

Проблема заключается в том, что если ошибка происходит createObservable будет закрыт, поэтому я не буду получать какое-либо Next события в будущем. Я попытался использовать retry(), но, похоже, это вызовет тупик, контроллер просмотра больше не сможет ответить на какое-либо событие касания. Так может кто-нибудь сказать мне, как решить эту проблему? Большое спасибо

viewModel!.createObservable.retry().subscribe(onNext: {[unowned self] (obj:PassbookModelType?) -> Void in 
    if let _ = obj{ 
     self.dismissVC() 
    } 
}, onError: { (error) -> Void in 
    print(error) 
}).addDisposableTo(self.dispose) 

ответ

2

Я предлагаю сделать тип createObservablePublishSubject<Observable<PassbookModelType>>, вместо BehaviorSubject<PassbookModelType?>, который, я думаю, случайно сглаживает два Rx потоки концептуально separatable друг с другом: сам (процесс один выстрел) saveObject процесс и начиная с процесса saveObject, инициированного действием пользователя. Я написал короткий пример, чтобы продемонстрировать это.

let createObservable = PublishSubject<Observable<Int>>() 

override func viewDidLoad() { 
    super.viewDidLoad() 
    createObservable.flatMap { 
     $0.map { obj in 
      print("success: \(obj)") 
     } 
     .catchError { err in 
      print("failure: \(err)") 
      return empty() 
     } 
    }.subscribe() 
} 

// Simulates an asynchronous proccess to succeed. 
@IBAction func testSuccess(sender: UIView!) { 
    let oneShot = PublishSubject<Int>() 
    createObservable.onNext(oneShot) 
    callbackAfter3sec { res in 
     oneShot.onNext(1) 
     oneShot.onCompleted() 
    } 
} 

// Simulates an asynchronous process to fail. 
@IBAction func testFailure(sender: UIView!) { 
    let oneShot = PublishSubject<Int>() 
    createObservable.onNext(oneShot) 
    callbackAfter3sec { res in 
     oneShot.onError(NSError(domain: "Error", code: 1, userInfo: nil)) 
    } 
} 

func callbackAfter3sec(completion: Int ->()) { 
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(NSEC_PER_SEC * 3)), dispatch_get_main_queue()) { 
     completion(2) 
    } 
} 

Существует важная заслуга в том, что: Если процесс один выстрел стал бы в стиле Rx (например, как в качестве callbackAfter3sec() -> Observable<Int>) в будущем, не было никакой необходимости переписывать потребительных как в приведенном выше viewDidLoad. Существует только одно изменение - передать объект Observable<> на createObservable.onNext(...).

Извините за мое плохое владение английским языком. Надеюсь, это имеет смысл для вас.

Смежные вопросы