首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RxSwift PublishSubject无意中被处置

RxSwift PublishSubject无意中被处置
EN

Stack Overflow用户
提问于 2017-11-15 20:41:07
回答 1查看 1.5K关注 0票数 2

我有一个,它打开一个模态视图控制器,让用户从它的库中选择图像。为此,我使用了我编写的DKImagePickerController的Rx包装器。

视图控制器中的相关代码如下:

代码语言:javascript
复制
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)
}

我的视图模型如下所示:

代码语言:javascript
复制
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)
      }
}

当我打开第一个模式选择器时,它会像预期的那样工作。然而,当它处理时,视图模型中的绑定也会处理,因此模态视图控制器的后续表示将无法工作。

下面是我在控制台中得到的日志,它可以帮助您理解我看到的内容:

代码语言:javascript
复制
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

如果我将视图控制器中的代码更改为如下所示:

代码语言:javascript
复制
    pickerController.rx.didSelectAssets()
        .debug(" 1")
        .subscribe(onNext: { (asset) in
            viewModel.addAssetsInput.onNext(asset)
        })
        .disposed(by: disposeBag)

它如预期的那样工作。但是,在这种情况下,我发现使用bind更优雅,如果可能的话,我希望继续使用它。

是什么触发了视图模型中PublishSubject的绑定以进行释放?我怎样才能在不泄露资源的情况下防止这种情况发生?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-20 00:56:08

我怀疑,因为completed通过第二链(MediaViewModel.bind中的一个)传播,它将不再接收任何事件。我认为您应该在这里使用subscribe(onNext: { ... })而不是bind,这样就可以避免发送错误和完成事件。

另一种选择是使用PublishRelay而不是PublishSubject

PublishRelay是PublishSubject的包装器。与PublishSubject不同,它不能因错误而终止或完成。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47316858

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档