使用observeOn和subscribeOn来解决我的应用程序冻结问题

时间:2016-09-18 05:02:56

标签: ios multithreading grand-central-dispatch rx-swift moya

我遇到很多用户抱怨他们的应用程序冻结,我怀疑这是由于网络请求。

很难再现,但我的解决方案是将subscribeOn和observeOn添加到我的自定义mapArray函数中,该函数在moya请求之后但在任何ui使用之前被链接。

问题:

  • 这个调用subscribeOn和observeOn的顺序是否有意义解决冻结问题?
  • 在调用函数之后调用subscribeOn 感觉很奇怪,但我不想将我的请求包装在另一个调度块中

总的来说,我对Moya和Alamofire中的线程切换非常困惑,希望有人可以发光:

PS:我已经阅读了issue in moya讨论这个问题,它提到alamofire在主线程上进行网络调用,这也让我感到困惑

PS2:此解决方案也基于此blog post,但我的问题,除了上述问题之外,为什么它可能提倡在后台线程上运行网络调用时,看起来不是这样的对于莫亚人来说。

 // How the network call is 
 func load() -> Observable<Void> {
    let apiProvider: RxMoyaProvider()
    return apiProvider.request(.GetFeed(page: 1))
      .mapArray(Question.self, keyPath: "questions")
      .doOnNext { questions, pagination in
        // updates the results to a variable, which is bound to the UI
        self.pagination = pagination
        self.data.value = questions
      }
      .flatMapLatest { _ in
        Observable.just()
      }
  }

 // My observable extension, a function to map responses to a 
extension ObservableType where E == Response {

  func mapObject<T: Mappable>(type: T.Type, keyPath: String) -> Observable<T> {
    return
      // this makes sure that the beginning of the call is made on the background thread. but it can be changed later, so we need an observe on later on
      subscribeOn(ConcurrentDispatchQueueScheduler(globalConcurrentQueueQOS: .Background))
      .doOnError(networkFailureCallback)
      .filterSuccessfulStatusCodes()
      .handleUnauthorizedRequest()
        // this makes sure that the mapping happens on a background thread as well
      .observeOn(ConcurrentDispatchQueueScheduler(globalConcurrentQueueQOS: .Background))
      .flatMap { response -> Observable<T> in
        return Observable.just(try response.mapObject(T.self, keyPath: keyPath))
      }
  }
}


// In my viewController
dataAccessor.load()
  .observeOn(MainScheduler.instance)
  .subscribe { error in
    // do actions
  }
  .addDisposableTo(self.disposeBag)

0 个答案:

没有答案