簡體   English   中英

RxSwift PublishSubject意外處置

[英]RxSwift PublishSubject getting unintentionally disposed

我有一個視圖控制器,可以為用戶打開模式視圖控制器以從其庫中選擇圖像。 為此,我使用了我編寫的DKImagePickerController的Rx包裝器。

視圖控制器中的相關代碼如下:

fileprivate func addPicturesFromLibrary() {
    guard let viewModel = self.viewModel else { return }

    let pickerController = DKImagePickerController()
    pickerController.singleSelect = false
    pickerController.maxSelectableCount = 10
    pickerController.showsCancelButton = true
    pickerController.sourceType = .photo

    pickerController.rx.didSelectAssets()
        .debug("👍 1")
        .bind(to: viewModel.addAssetsInput)
        .disposed(by: disposeBag)

    self.present(pickerController, animated: true, completion: nil)
}

我的視圖模型如下所示:

class MediaViewModel {

      var selectedImages = Variable<[MediaListingImage]>([])

      public let addAssetsInput = PublishSubject<DKAsset>()

      init() {
         bind()
      }

      private func bind() {
          addAssetsInput
              .debug("👍 2")
              .flatMap {
                  $0.rx.fetchOriginalImage()
              }
              .map {
                  MediaListingImage.local($0)
              }
              .subscribe(onNext: { [weak self] (mediaListingImage) in
                  self?.selectedImages.value.append(mediaListingImage)
              })
              .disposed(by: disposeBag)
      }
}

當我打開第一個模式選擇器時,它會按預期工作。 但是,當它處理時, 視圖模型中的綁定也將處理,因此模式視圖控制器的后續表示將不起作用。

這是我在控制台中獲得的日志,它可能有助於您了解我看到的內容:

2017-11-15 17:33:15.490: 👍 2 -> subscribed
2017-11-15 17:33:21.452: 👍 1 -> subscribed
2017-11-15 17:33:23.902: 👍 1 -> Event next(<DKImagePickerController.DKAsset: 0x6080002ab940>)
2017-11-15 17:33:23.902: 👍 2 -> Event next(<DKImagePickerController.DKAsset: 0x6080002ab940>)
2017-11-15 17:33:23.902: 👍 1 -> Event completed
2017-11-15 17:33:23.903: 👍 2 -> Event completed
2017-11-15 17:33:23.903: 👍 2 -> isDisposed
2017-11-15 17:33:23.903: 👍 1 -> isDisposed
2017-11-15 17:33:29.924: 👍 1 -> subscribed
2017-11-15 17:33:33.114: 👍 1 -> Event next(<DKImagePickerController.DKAsset: 0x60c0002a62a0>)
2017-11-15 17:33:33.114: 👍 1 -> Event completed
2017-11-15 17:33:33.114: 👍 1 -> isDisposed

如果我將視圖控制器中的代碼更改為類似以下內容:

    pickerController.rx.didSelectAssets()
        .debug("👍 1")
        .subscribe(onNext: { (asset) in
            viewModel.addAssetsInput.onNext(asset)
        })
        .disposed(by: disposeBag)

它按預期工作。 但是,我發現在這種情況下使用bind更優雅,如果可能的話,我希望繼續使用它。

是什么觸發了視圖模型中要處理的PublishSubject綁定的處理? 如何避免資源泄漏?

我懷疑是因為completed通過第二個鏈( MediaViewModel.bind的一個)傳播了,所以它將不再接收任何事件。 我認為您想在這里使用subscribe(onNext: { ... })而不是bind這樣就可以避免發送錯誤和完成事件。

另一種選擇是使用PublishRelay而不是PublishSubject

PublishRelay是一個包裝PublishSubject PublishSubject不同,它不能因錯誤或完成而終止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM