3

我的视图模型中有一个BehaviorSubject名字createObservable。我的视图控制器订阅它。

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)
4

1 回答 1

2

我建议制作 的类型createObservable PublishSubject<Observable<PassbookModelType>>,而不是BehaviorSubject<PassbookModelType?>我猜想,它会意外地将两个 Rx 流在概念上彼此分离: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)
    }
}

这样做有一个重要的优点:如果 one-shot 过程将来会变成 Rx 风格(例如,像 as callbackAfter3sec() -> Observable<Int>),则不需要像上面那样重写使用端代码viewDidLoad。唯一要做的改变就是将一个Observable<>对象传递给createObservable.onNext(...).

对不起,我的英语水平很差。我希望这对你有意义。

于 2015-11-24T05:18:39.097 回答